Skip to main content

Full text of "The Essential Guide To Timex Sinclair Home Computers"

See other formats


with a Special Section on the Timex/Sinclair 2000 


THE ESSENTIAL GUIDE TÜ 
TIMEX/SINCLAIR 
HOME COMPUTERS 


! The Only Book You'll Ever Need to Become an 
| Expert at the Timex/Sinclair 1000 and 2000 


li 






ЖДД ЕТП 





: f 


"d 


cundo 3H YIVIINIS/KIWIL 












ñ. E 1 ' Е E 
МУГ ы ЕК 
ie L E S M 4 % 5 | а 
\ ( ' “ [| | li ( ү ж | я , TY 7 ` ` 
| E 4 є d] j = у | et Ties | А | E 
ч т, d x I ^ ; s a | - 
EN А Gs > 
i E»: "A 


"v 4 
y "4p". 








THE ESSENTIAL GUIDE TO 


TIMEX/SINCLAIR 


HOME COMPUTERS 


The Only Book You'll Ever Need 
to Become an Expert 
at the Timex/Sinclair 1000 and 2000 


by 
PETER MORSE, IAN ADAMSON 
BEN ANREP and BRIAN HANCOCK 


A TOUCHSTONE BOOK 
Published by Simon & Schuster, Inc. 
NEW YORK 


We are grateful to Sinclair Research for their cooperation 
This book was published in England under the title The Century 
Computer Programming Course 

Copyright © 1983 by Eosoft 

All rights reserved 

including the right of reproduction 

in whole or in part in any form 

A Touchstone Book 

Published by Simon & Schuster, Inc. 

Simon & Schuster Building 

Rockefeller Center 

1230 Avenue of the Americas 

New York, New York 10020 

Published by arrangement with Century Publishing 
Company, England 

TOUCHSTONE and colophon are registered trademarks of 
Simon & Schuster, Inc. 

Manufactured in the United States of America 

10 98 765 43 2 1 Pbk. 


Library of Congress Cataloging in Publication Data 
Main entry under title: 


The Essential guide to Timex/Sinclair home computers. 
(A Touchstone book) 
British ed. published as: The century computer programming course. 
1. Timex 1000 (Computer)—Programming. 2. Timex Sinclair 2000 
(Computer)—Programming. 3. Basic (Computer program 
language) I. Morse, Peter (Peter L. R.) II. Title. 
QA76.8.T48E77 1983 001.64'2 83-9090 
ISBN 0-671-47069-8 Pbk. 


IMPORTANT NOTE FOR ALL READERS 


This book uses the Sinclair version of single keystroke BASIC as 
featured on the ZX81 and Spectrum microcomputers. In the States the 
ZX81 has been marketed as the Timex/Sinclair 1000 and the 
Spectrum is known as the Timex/Sinclair 2000. American readers 
should note that throughout the text we refer to these machines by their 
UK names. There are a few minor differences between the UK version 
of the ZX81 and the US TS 1000. The first is that the TS 1000 has 
more ‘on board’ memory (2k) than its UK equivalent. However, this is 
still insufficient for the scope of this text, and the majority of the 
programs occurring in the book will require a 16k RAM pack. The 
second difference is that two keys, which do exactly the same thing, are 
labelled differently. Thus, NEWLINE and ENTER are equivalent on 
the ZX81 and the TS 1000, as are RUBOUT and DELETE. On each 
occasion that these commands occur in the text, readers will find either 
NEWLINE (ENTER) or RUBOUT (DELETE). 

For the sake of clarity we have used the ZX81/TS 1000 version of 
BASIC as the foundation of the book, and have noted those instances 
where Spectrum (TS 2000) BASIC differs from that used by the ZX81 
(TS 1000). Functions and commands exclusive to the Spectrum (TS 
2000) BASIC superset are fully explained at the end of the book (Units 
W2 and W3). 

In short, the book has been designed to enable its readers to learn 
how to program using any of the Sinclair machines. 

Users of the Spectrum should note that all programs are listed in 
capital letters throughout. To get program results and listings that look 
identical to those given here the capital letter (CAPS) mode must be 
used on the Spectrum for all letters input or printed. The first two 
Units of Part One deal only with the ZX81. The Spectrum user should 
read instead Unit W1 (page 439) of the Spectrum dedicated Section 
which forms Part Five of this text. 











TE 
РЧ КЛ АЙ oie SOT TOM ГИЛ ГАГИ 


í; FAD iin “ger former үніне” wh еи фе” ИЯ? 
= ez deus qo +. теі Craft <p dj Lente ' ` лу me imos 
чї Мг» ОҒ” tint G ete ГГ м” +, бағала Cow sa ТЕК 
«rues scores НЕ qub uncuoncul wit а nmond W (tre 
ИЛЕ ow ai z p Op ron HE ыы. sec anda ses ФИИ» 
twee S cigs о of Ohh roues xml en Ж!) 
qi NyEL. x м mh n pert of] GONE < T т. si are BM ani b. 
4 nd: wywal aaarnas AF on amn ri yea bear fo оса) 
яй 6 ышы нір Куе ЯҰ woli ba урт» wh) аа sailon Hor 
Wh idea MIO кч „шшр |І) Vest wll i pen ун» АЫ 
ө.ж”, ӘР diliang i dial, of «4 a1 64 bt шут ЇЙ, wane 
hoe {йз етю 6 APPAR һа, 771249 145 Ant dherek Баъ 
Ao ore? Fe 0 (has ТИТЛ 113 92:9 NODI VV йз 183 рм 
‚2; d mb e: „і Waq; үт л ыз Ыл —2 боза" Ted onda М) 
«ІЛМЕ РБЬӨГІЯ- тұр n TOELIWSƏ 
bite ote VUE *+ et x уй іу” vu үз ques ne der чу e 


жүз, SO k n ffm, (is /4 % .л.ілыкт wp ee "ul 
1» 477 how Yani Ch. trace “ҰРТ Kin: 4 QUITE чи ЫЫ ey 
5%% “Мз. é OF a $n» vy TIME 71 m і unie 1469! at 
we 132 — 4 quies b oO ізнігіп iios suus ЯРЛЯ AON 

4 pis SW 


Y vnum & Айды!) Paige S=) a ved ¿P өсік ті 
И айел Heine, wtih у, Эл потр Н Qam 
4 ood boue sg dr ei іл. Oni шр че att 6. nme 
мұ», 4 À) * уй Пул vndas ac) чода, er vm 49» 
ы) wh * gop cm Fe . Á p? - M" Ж 4% el ба) „ aml 2), te darmi 


LU EP "d Ris $ nf += == E | 2998 wi! 7", бузат 
биз с» uar а” © M* pt die Laus 240 - of =n mae 

4 E m. il Т” 1: m ( f 1:31 І а €2 Js gyi 
a F 7“ 41 y - cl * m. 





CONTENTS 


page 
Introduction xiii 
PART ONE 
FIRST STEPS xvii 
SECTIONA THEZX81 MICROCOMPUTER SYSTEM l 
А! 7Х81 System Description 
A2 Function of Components + 
SECTIONB GETTING TO KNOW THE ZX81 7 
ВІ Connecting Up 
B2 Тһе Keyboard 9 
B3 Cursors 10 
B4 ‘The Different Character Types 12 
SECTION C BASIC BASIC 19 
СІ Тһе BASIC Language 19 
C2 А Simple Program 19 
СЗ  AStatement 20 
C4 Statement Numbers 20 
C5 Instructions 21 
C6 Numeric Variables 21 
C7 Strings and String Variables 23 
C8 Operators and Operands 24 
C9 Format of Statements 24 
C10  Keying in a Statement 24 
C11  Correcting Errors 26 
C12 Commands 27 
C13 Editing the Program 28 
C14 Listing a Program on the Screen 29 
C15 Running the Program 29 
C16 Error Messages 31 
C17 How the Program Works 32 
C18 Naming the Program 33 


SECTIOND SAVING, LOADING AND LISTING PROGRAMS 35 


D1 Saving the Program on Cassette Tape 35 

D2 Deleting the Program from Memory 38 

D3 Loading the Program from Cassette Tape 40 
vii 


D4 
D5 


Listing the Program on the Printer 


Program Libraries and Directories 


SECTIONE IMPROVING THE PROGRAM 


El 
Е2 
ЕЗ 
Е4 
Е5 
E6 


Adding Comments 

Using the Print Statement 
Adding a Loop 

Stopping the Program 
Testing for a Condition 
Final Edit and Saving 


SECTION F A GAME INTERLUDE 


El 
F2 


The Program Library 
A Game to Key In 


PART TWO 
ESSENTIALS OF BASIC PROGRAMMING 


SECTION G PROGRAMMING METHODS I 


G1 
G2 
G3 
G4 
G5 
G6 
G7 
G8 
G9 
G10 


Programming 

Problem Analysis 

Structure Diagrams 
Classifying Program Modules 
Control Structures 

The Data Table 

Describe the Algorithm 

The Pseudocode Description 
Flowcharts 


Testing the Algorithm 


SECTIONH CONTROL 


H1 
H2 
H3 
H4 
H5 
H6 


Control in Programs 
Condition Testing 

IF-THEN 

GOTO Instructions 

Decision Structures 

Logical Operators: AND/OR 


SECTIONI PRINTING 


I1 
I2 


PRINT/LPRINT 
Spacing Items on the Screen 


viii 


57 


43 
44 


46 
46 
46 
47 
48 
49 
51 


53 
53 
53 


59 


59 
60 
63 
65 
67 
70 
72 
73 
74 
84 


86 
86 
86 
87 
88 
89 
96 


99 


99 
100 


ІЗ 
14 


РКІМТАТ 
Тһе Graphics Characters оп (һе ZX81 


SECTION J ARITHMETIC AND FUNCTIONS 


Ji 
J2 
J3 
J4 
JS 
J6 
J7 
18 
19 
Ј10 
wil 
112 
113 


Arithmetic Operations 

Priority 

Number 

The E Notation 

Rounding 

How Numbers are Handled 
Function 

List of Functions in Sinclair BASIC 
The Function Characters 

The Function Character Set 

The Standard Mathematical Functions 
Trigonometric Functions 


Special Functions 


SECTION K STRINGS 


K1 
K2 
K3 
K4 
K5 
K6 
K7 
K8 
K9 
K10 
K11 
K12 


Strings 

Quotes and Quote Image 

String Input 

Length of a String 

Null Strings 

String and String Array Variables 
String and String Array Dimension 
String and String Array Assignment 
Substrings and String Slices 

String Concatenation 

Comparing Strings 


Strings and Numbers 


SECTION L LOOPS 


L1 
L2 
L3 
L4 
L5 


Loops 

Counters 

FOR-NEXT Loops 
Loops of Variable Length 
Nested Loops 


SECTIONM PLOTTING 


MI 
M2 


PLOT and UNPLOT 
Graph Plotting 
IX 


102 
104 


108 


108 
108 
111 
111 
114 
115 
116 
117 
118 
119 
120 
122 
123 


126 


126 
127 
128 
130 
130 
131 
131 
132 
133 
135 
136 
139 


142 


142 
143 
147 
153 
155 


159 


159 
162 


SECTIONN SUBROUTINES 


N1 
N2 
N3 
N4 
N5 
N6 


Subroutines 
Subroutine Example 
Nested Subroutines 
Recursive Subroutines 
Computed GOSUBs 


Subroutine Use: Example 


PART THREE 


ADVANCED BASIC PROGRAMMING 


SECTIONO PROGRAMMING METHODS II 


Ol 
O2 
O3 
O4 
O5 


SECTION P THE CHARACTER SET AND CODES 


Р1 
P2 
P3 
P4 


Resume 

Producing the Program 
Coding and Design 
Program Development 


The Complete Programming Method 


The ZX81 Character Set and Codes 
The Spectrum Character Set and Codes 
Characters 


CHR$ and CODE 


SECTION Q GRAPHICS 


O1 
Q2 
Q3 
Q4 


More Printing 

More Plotting 
Movement and Timing 
The Display File 


SECTION R LOGICAL OPERATIONS 


R1 
R2 
R3 
R4 
R5 
R6 
R7 
R8 
R9 
R10 


Logical Values and Numeric Values 
Boolean Operators: The AND Operator 
The OR Operator 
The NOT Operator 
Conditional Operators 
Logical Operations on Conditional Expressions 
Multiple Logic on Conditions 
Logical Operations on Numbers 
Priority 
Logical Operations with Strings 

X 


169 


169 
170 
172 
172 
177 
179 


R11 Logical Operations Between Strings and Conditions 


R12 Logical Operations Between Numbers and Conditions 


R13 Applications of Logical Operators 


SECTIONS LISTS AND ARRAYS 


51 Dimension 

S2 Index Variable 

S3 Lists 

54 Examples of Lists 

S9 String Arrays 

S6 Two Dimensional Numeric Arrays 
57 Multi dimensional Arrays 

S8 | Useof Arrays 


SECTION T SORTING, SEARCHING AND STORING ARRAYS 


T1 Searching and Sorting 
T2 Bubble Sort with Flag 
T3 Alphabetic Sort 

T4 Insertion Sort 

T5  ShellSort 

T6 Quick Sort 

T7 Index Sort 

T8 Linear Search 

T9 Binary Search 

T1Q Storing a List 

T11 Storing a String Array 
T12 Storing Data in Strings 


SECTION U THE COMPUTER MEMORY 


U1 Memory Organisation 
U2 PEEK and POKE 
ОЗ System Variables 


PART FOUR 


APPLICATIONS PROGRAMS AND GAMES 


SECTION V APPLICATIONS PROGRAMS 


V] Programming for Applications 
V2 Instructions and Input Checks 
V3 Example Programs 


V4 Games Programming 


xi 


351 


270 
271 
272 


279 


279 
279 
280 
280 
283 
284 
286 
287 


292 
292 
294 
295 
296 
299 
302 
306 
309 
310 
312 
314 
316 
319 
319 
325 
332 


353 


299 
354 
359 
425 


V5 Example Programs 426 


PART FIVE 
COVERING THE WHOLE SPECTRUM 437 


SECTIONW THESPECTRUM 439 
W1 The Spectrum System and Keyboard 439 
W2 Additional Spectrum BASIC Functions 456 
W3 Graphics, Colour and Sound 466 


APPENDICES 477 


I Sinclair BASIC Summary 477 
II Error Codes 483 
HI ZX81 Character Codes by Keyboard Arrangement 487 
ГУ Use of Cassette Tapes 491 
V System Variables 493 


VI Program Library 499 


хи 


INTRODUCTION 


The central conviction behind this book is that programming 
computers to solve problems is essentially a language independent 
activity. This means that there is no reason why Sinclair BASIC should 
not be learnt in exactly the same way as other high level languages: that 
is, with the fundamentals of problem solving апа structured 
programming introduced at an early stage. For the majority of readers, 
Sinclair BASIC will be their first introduction to computing. We would 
like to think that many will use it as a stepping stone to more advanced 
study and application. Good problem solving and programming habits 
will make both applications programming in BASIC and learning a 
different structured language like PASCAL (which has a richer 
programming environment than BASIC), much easier. We are 
convinced that bad programming habits acquired early on are 
extremely difficult to throw off; thus, this book has been designed to 
introduce readers to the elements of computer programming in a 
systematic manner, with the emphasis on correct rather than merely 
adequate techniques. 

Although we intend the text to be a serious treatment of Sinclair 
BASIC, ав an introduction to computing it assumes по prior 
knowledge of computers and only a minimal understanding of 
mathematics. (Without the maths you will still be able to make your 
way through the book, but if you don’t know what SIN and COS are, 
you won’t be able to write programs using them!) Before all else, we 
intend to give readers a full introduction to the essential control and 
modular structures present in truly structured computer languages and 
the way in which they operate in Sinclair BASIC. Once again, we hope 
that with this behind them, readers will be able to go on to tackle more 
sophisticated computer languages with a clear understanding of the 
essentials of good programming in any language. This approach also 
ensures that the reader who stays with his Sinclair machine will be able 
to maximise its potential. As it runs on the world’s most popular 
microcomputers, there can be little doubt that Sinclair BASIC will 
become one of the most commonly used computer languages. This, 
coupled with the fact that more and more software is becoming 
available for the machines, makes it all the more important that users 
attain a sound understanding of the language. Most published 
programs in books and magazines have little in the way of 
documentation. Debugging them, normally a tedious and difficult 
task, becomes much easier if the techniques to do so are known. 


This book introduces readers to three main sets of computer rules: 
1 The rules of using your computer system. 

2 The rules of the Sinclair BASIC programming language. 

3 The rules of problem solving and structured programming using 


Sinclair BASIC. 


xiii 


WHY DID WE WRITE THIS BOOK? 


The sheer availability of the Sinclair machines demands that they be 
treated seriously as a means of teaching progamming methods to a 
large number of people. The programmer of a personal computer must 
understand the characteristics of the machine, the high level language 
(in this case BASIC), by which it is used and controlled and the 
problem solving techniques to which it should be applied. 

The first rush of books on the Sinclair machines has been, to put it 
kindly, disappointing. Certainly none can be considered a serious text 
on Sinclair BASIC. We felt that a book was needed which gave the first 
time user a worthwhile home tutor on computing. So we decided to 
write one! 


WHO IS THE BOOK FOR? 


The book has been written for the home user or school user who has 
just bought a ZX81 or Spectrum and wants to learn how to program it 
from scratch. Experience has shown that most Sinclair users will buy 
more than one book on the subject of programming their machine. 
This book will clear up a few misunderstandings and confusions 
presented by other texts and will take you further into programming 
techniques. 

The text has also been designed as an aid to Sinclair BASIC 
programmers who are having trouble designing error free programs 
and are attempting some serious application. 


HOW IS THE BOOK STRUCTURED? 


As a self-study text, this book should be worked through with your 
computer in front of you, so that programs and examples can be keyed 
in as and when they arise. 


The book has twenty-three Sections and is divided into five Parts. 

Part 1: FIRST STEPS in which, after a brief introduction to the 
machine and system (the first two units are ZX81 specific, and 
Spectrum users should go immediately to the Spectrum specific 
units - W1 on page 439 - before returning to start the main text at 
Section C) you are told how to set it up correctly and start to write and 
run simple BASIC programs. 

Part 2: FUNDAMENTALS OF BASIC PROGRAMMING, which 
first introduces the reader to the fundamentals of problem solving and 
structured programming in BASIC. Тһе properties and 
implementation of important language CONTROL 
STRUCTURES - decisions, loops, and subroutines - are introduced, 
together with the use of arithmetic, functions, strings, and how to print 
and plot information on the screen. 

Part 3: ADVANCED BASIC PROGRAMMING contains further 
sections on programming methodology, as well as details of debugging, 

XIV 


testing and documenting programs. Interactive graphics is introduced, 
together with the use of logical operators. Lists and arrays and methods 
to sort and search them (vital subjects for applications programming) 
and a treatment of how the computer uses its memory are fully 
covered. 

Part 4: APPLICATIONS PROGRAMMING AND GAMES 
focuses the fundamental programming skills acquired in the earlier 
parts of the book in the study of specific examples, linked to some 
further discussion of programming technique. 

Part 5: COVERING THE WHOLE SPECTRUM is the portion of 
the book dedicated to the Spectrum. The first Unit of this Section, 
dealing with the Spectrum system and keyboard, replaces the ZX81 
specific Sections A and B, since there are major differences in the 
arrangements of the two machines which require separate treatment. 
The two following Units in this Part of the book deal with additional 
features of the Spectrum not covered in the main text. It is intended 
that, after using the first Unit to acquaint him or herself with the 
Spectrum, the reader should defer reading these Units until the main 
body of the text has been worked through. For the Spectrum user, this 
starts at Section C. 

The book is detailed and thorough. Remember that programming is 
learned most effectively through experience. You should work through 
the text systematically using your computer. Key in each example in 
the text and run it. Some further programs to key in are available in 
Appendix VI. 

The exercises which appear at regular intervals throughout the book 
are meant to give you practice in programming methods and to further 
illustrate the function and application of the Sinclair BASIC language 
constructions. Attempt most of them, but don’t ever allow yourself to 
become discouraged. If you get stuck, go back through the relevant 
section again. 

We hope that you find learning BASIC programming with this book 
a successful, enjoyable and useful experience, and that the knowledge 
and programming skills obtained will be a step on the path to a more 
advanced use of your Spectrum or ZX81 for real applications and 
enjoyment. 


XV 








ІҢ 





$E 


ІН 

















H 





dand pd 


ІН 


pur tips SMS, AN Cree 
iwi S4 Шаға Mad өш do^ > eet 7 bonua «canted 
‘Hee Kets? 
volut. йй ay aint arrests ПОЛО grieved bets) tao tari ed gn 
deabus nord бы? чый oe sura age Tiber: iron «М. заз (eo m £ 
-GA < ihe и ж ула % «©.» {кулан Ya кзжсжттер bgr 
там, ъз + Min Pí Г ұлығ | nus зыр“ iai паз 1 D нұйуі, 


АТИ 





PART ONE 


FIRST STEPS 


Important Note: The first two units of this part are 
specific to the ZX81. Spectrum users should ignore these 
pages and directly GOTO the first Spectrum specific 
section (W1 on page 439) before returning to the main 
text (Section C on page 19). 








Зин ERAS 





LI 
рч 





SECTION A: ZX81 MICROCOMPUTER SYSTEM 


A1: ZX81 Description 


We assume you have in front of you the components of your ZX81 
computer system. 

It consists of: 

1 Тһе ZX81 microcomputer with its touch-sensitive keyboard. 

2 The Sinclair 16k RAM pack (Random Access Memory) or a 
RAM pack of at least 16k produced by one of the other 
manufacturers for the ZX81. 

3 The ZX power supply, with a lead and plug, for connection to 
the a.c. power supply, and the lead, ending in a jack-plug, to 
connect the power supply unit to the ZX81. 

4 The ZX printer and its connector socket. 

A domestic UHF ТУ set to be used as a TV monitor. 

6 А mono cassette recorder, with power supply lead if not battery 

powered. 

The aerial cable which connects the ZX81 to the TV monitor. 

8 A pair of cassette recorder leads fitted with 3.5mm jack-plugs оп 
each end. 


сл 


I 


These components make up a complete system. As far as this text is 
concerned, the least crucial component is the printer. Without it you 
can simply ignore the printer-related portions, and will be able to work 
through the book and learn the BASIC programming techniques just 
as well. However, it is extremely useful to have a printer both for hard- 
copy printouts of results, and more importantly for program listings for 
documentation purposes. 

There are a large number of ‘add-ons’ and accessories available for 
the ZX81. None of these are of any interest as far as this book is 
concerned, and most should be considered only when you have 
absorbed the text and are going to write programs for specific purposes, 
which might require the facilities provided by some of these units. A 
noteworthy exception is a workstation to hold the components of the 
system securely. There are types available which have on/off switches 
for the d.c. power supply from the power supply unit, which saves a lot 
of plug pulling and re-insertion, since pulling the power plug out of the 
ZX81 is the only way to re-set the computer if it ‘crashes’ (i.e. will not 
respond to keyboard commands). 

What ¿s vital is enough memory. RAM memory is measured by 
kilobytes (‘k’). The basic ZX81 has only 1k of RAM built in (2k on the 
Timex/Sinclair 1000), and, without an add-on, RAM memory has 
very little space available for programs. Computers are essentially 
devices which store and manipulate data, and since programs, data, 
and the manipulations all take up memory space, an add-on RAM 


1 





Figure 1 


ZX81 SYSTEM DIAGRAM 


ас. household power supply 


AERIAL 
TV MONITOR SOCKET 






POWER 
EAR а CASSETTE SUPPLY 


МІС | RECORDER 








NOTE: U.S. USERS MAY HAVE ANTENNAE ON/OFF SWITCH FITTED IN AERIAL 
LEAD, SHOWN AS DOTTED BOX IN DIAGRAM. 


memory is needed. RAM memory of up to 48k is available for the 
ZX81, but 16k is more than enough for our purposes. Independently 
produced RAM packs are usually just as good as those produced by 
Sinclair. 

The cassette recorder should be mono, since stereo tape deck 
recording heads can cause problems, even used on one channel only. 
The cheaper recorders work somewhat better (due to the less 
sophisticated audio circuits being better for handling the crude form of 
the computer’s signals) than more expensive ones, but try to get one 
with a tape counter, as finding programs without one can be 
irritatingly time consuming. You should always use the same recorder, 
as problems can be encountered when playing back tapes recorded on a 
different machine. Battery-operated recorders actually avoid some 
potential problems, but must always have good batteries, to keep tape 


2 


speed constant. The cheapest solution to this in the long term 
(especially since if you're not sure about the state of the batteries you 
have to put in new ones) is to buy nickel-cadmium batteries and a 
charging unit. All recorders have automatic level controls for 
recording, but some cause problems with their continual variation 
around the correct level (‘hunting’). Get a model that has been shown 
to be compatible with the Sinclair computers. 

Having a TV for exclusive use with your computer system 1s a good 
idea, to avoid having to unplug and move around elements of your 
system (it also avoids arguments with non-computing members of the 
family!). 

Some problems can interfere with the operation of your computer 
(leaving to one side things like spilling coffee on it or otherwise abusing 
it!). The first is overheating. After the computer has been on for some 
time, it may heat up to such an extent that it ‘whites out’ and wipes out 
the program you have just finished, except for that last line. This is 
very irritating, to say the least. Some ZX81s seem to suffer from this 
more than others. If it is a persistent problem, it can be helped by 
placing a fairly hefty chunk of metal on top of the case to radiate heat 
away more effectively. It should be approximately 3 x 2 inches and 0.5 
inch deep, have a flat surface to sit on the ZX81 case, and should be 
placed on the case, above the keyboard, on the left-hand side of the 
case. 

lhe corollary to this problem is that you should SAVE a long 
program being developed or keyed in at intervals, and/or take listings 
from the printer, to avoid a total loss if you do get a white out. The 
same problem can also be caused by two other factors, and this 
procedure will protect against the worst results from these problems as 
well. The first is that household power supplies are sometimes 
interrupted, or occasionally have brief large voltage fluctuations. 
Computers are sensitive to such things, and a crash may be caused. 
Other than buying a stabiliser which will continue to supply power 
during such an interruption (of very short duration, but computers 
work fast!) we cannot protect against a.c. supply fluctuations, but 
similar results can sometimes be caused by appliances connected to the 
same local power circuit switching on and off, and this should be 
investigated if the problem is frequent. 


The other main source of problems is the connector to the RAM 
pack and printer via the edge connectors at the back of the ZX81. 
Movement can be caused in this connector by flexing the system whilst 
keying in programs. This can be minimised by always pushing the 
connectors home firmly before switching on, but a better solution is to 
attach the components to a board, fixing them down to a suitably rigid 
base with ‘Blu-Tack’ or the double sided adhesive pads that are now 
available. Fix the printer down as well- the process of tearing off 
printout can move printer and connector if you are not careful. Note 
that the method of fixing cannot be permanent, which is why Blu- Tack 


3 


or a similar plastic fixative is recommended. 

The edge connectors themselves are gold plated, but they connect to 
the printed circuit board edges which may become oxidised, causing 
circuit problems (not necessarily white-outs or crashes — the keyboard 
may cease to work, or the printer miss lines, for example). Proprietary 
(non-abrasive) contact cleaners should be used to ensure clean 
contacts. 

Other than the problems above, the only maintenance that should be 
needed is the brushing away of the dust that accumulates in the printer 
from the burnt-off particles of paper. After removing the paper holder, 
use a soft small brush (e.g. a small paint brush) to clear away the dust. 
Pay particular attention to the slot in which the electrode runs, but if, 
as sometimes happens, the electrode is visible, do not disturb it. (The 
electrode is a small piece of wire which is normally not visible, but if 
BREAK has been used it can be left in the middle of the printer slot.) 


A2: Function of Components 


This is a programming text, not a manual on computer architecture or 
computer science. However, we thought it might be useful to provide 
you with a brief rundown of the functions of each of the components of 
your microcomputer system. 


Device Function 
ZX81 computer board Data processing and control of 
(inside case) information handling. Input 


from keyboard or cassette. 
Output to TV screen and 
printer. 


Keyboard Input of information. Programs, 
data and commands are keyed 
in. On-line control. 


TV set Used as V.D.U. (visual display 
unit) monitor. Provides on-line 
output of information — visual 
display of programs, results 
(data, graphs, pictures) and 
control commands. 


Cassette recorder Off-line storage of information. 
Program data are stored (written) 
as coded electromagnetic 


impulses on cassette tapes. They 
can be played back (loaded) at 
any time for use again. The 
computer reads the data from 
the tape. 


ZX printer Output device, to provide a 


permanent printed record of the 
screen display, program listings 
or information in the computer 
memory. Prints on 
electrosensitive paper. 


16k RAM pack Add-on memory enabling large 


Power 


Cables 


programs to be stored and run. 
K stands for kilobyte. One byte is 
eight 22/5, which аге the binary 
digits (0 and 1, represented by 
on-off switches in the computer) 
computers work with. A kilobyte 
is roughly 1000 bytes, hence the 
name. (It is actually 29, 1024). 


supply Supplies the d.c. current (9 volts 
at 1.2 amps) to run the 
computer, RAM pack and 
printer, from the household 
power supply. 


To interconnect the devices 
which make up the system. The 
printer uses the same socket as 
the memory pack and has an 
extension socket to allow this. 


The printed circuit board inside the ZX81 holds and connects the IC 
(integrated circuit) microchips which provide the computing facilities. 


These 
1 


are: 
Z80A CPU (Central Processing Unit) microprocessor chip 
which is the heart of the system. It is used in many other 
microcomputers, and performs the arithmetic manipulations. 
ROM (Read Only Memory) chip holds the 8k BASIC 
interpreter which translates BASIC instructions into the 
machine code instructions that the Z80A operates with. The 
data in this chip is fixed, hence the name, and also stable — it 
remains when the power is switched off. 


3 RAM (Random Access Memory) chip provides a 1k* memory 
store. When the memory pack is fitted it blocks off this memory 
and substitutes its own 16k of memory. This memory is 
volatile — the data is stored as electrical impulses and is lost When 
the power is switched off. This memory stores the BASIC 
programs, the values of variables (including some system variables 
that the computer uses to organise its own affairs), a memory 
picture of the ТУ screen display, and the stacks which hold the 
numbers whilst they are being manipulated. This is covered in 
more detail in Section U. 

4 The Logic chip co-ordinates the operation of the other chips. 
Also mounted on the board are: the stabiliser for the 5 volt supply the 
computer takes from the power supply, the TV signal modulator and 
the sockets for the connecting cables to the ГУ and cassette recorder. 


*2k on the TS 1006. 


SECTION B: GETTING TO KNOW THE ZX81 


B1: Connecting Up 


1 


Lay out the ZX81 system devices on your work area as оп page 
2. It is far better to have an area where the system can be set up 
permanently. Failing this, a board can be used to mount the 
components. 


Place the a.c. power supply plugs of the power supply, ТУ and 
tape recorder next to the sockets. A plug board with multiple 
sockets mounted on it is better than an extension socket fitting. 
Connect the printer socket into the 23 pin edge connector at the 
back of the ZX81. Get the slot in the ZX81 board and the block 
in the printer socket aligned and push in gently but firmly. 
Connect the 16k RAM pack socket into the extension connector 
at the back of the printer socket in the same way. This is better 
done with the ZX81 flat on the table to avoid too much stress on 
the connectors, which might occur if you are holding up the 
LAB, 

With both connectors inserted, push the RAM pack firmly in to 
ensure the connectors are fully seated home. 

Connect the power supply cable into the socket marked DC on 
the left-hand side of the ZX81. 

Connect one end of the twin jack-plug leads, placing one jack- 
plug into each of the MIC and EAR sockets on the cassette 
recorder. 

Place the other jack-plugs into the ZX81 sockets. It is very 
useful to have the EAR and MIC sockets marked on the top of 
the ZX81 case, where the marks can be seen. Use sticky labels of 
some type to mark which is which, and also the exact centre of 
the plug socket. This will save much probing of sockets (there 
are no guides to ensure you get the socket) and peering at the 
markings on the side of the ZX81, which are scarcely visible 
when the ZX81 is flat on a surface. 

The yellow banded plugs should go to both MIC sockets. You 
can also mark the other jack-plug with E or EAR as a helpful 
aid. Push the jack-plugs gently in, making sure the tips are in the 
sockets (which has to be done by feel) until a resistance is felt, 
then push until they click into place. Waggle them slightly to 
ensure they are well-seated. 

Connect the aerial lead into the ТУ aerial socket at the rear of 
the TV and into the TV socket on the ZX81. A slight twisting 
motion may be needed if the fit is tight. 


US Users will find that the TV connects to the antenna lead with 
standard terminals, and an antenna ON/OFF switch is fitted between 
the antenna lead and the antenna lead that plugs into the 


7 


Timex/Sinclair 1000 version of the ZX81. This switch must of course 
be ON. 


Straighten the interconnecting cables on your work area at this 
point. Make sure that the cassette leads are not in contact with 
any a.c. power leads. 


SWITCHING ON 


оомо C 


10 


11 


12 


13 


Ensure that the TV receiver is off and that no cassette recorder 
keys are depressed. 

Plug the power supply, TV, and cassette recorder plugs into the 
a.c. power supply. 

Switch on the a.c. power sockets (if they have switches). 
There are no ON/OFF switches on the ZX81 or on most cassette 
recorders - they are now powered up. 

Switch on the TV. 

Turn the volume control on the ТУ to zero. 

Turn the brightness control to MAXIMUM. 

Turn the contrast control to MINIMUM. 

Tune in the TV. With a rotary tuning control, turn to channel 
36. Otherwise select a channel, using the pushbutton or other 
channel select switch, and tune this channel in. When the ГУ is 
at the right setting, a small black square with a white K inset 
appears. This is the K-cursor, and appears on the bottom left- 
hand side of the screen. 


U.S. Users should note that the Timex/Sinclair 1000 version of the 
ZX81 has a channel select switch for Channel 1 or Channel 2 fitted 
underneath the case. Choose whichever channel is not transmitting in 
your area, and select this channel on the TV and the computer. 


Adjust the tuning, brightness and contrast until the cursor is 
distinct, and the white K clear. 
Check that the cassette recorder keys function. Insert a blank 
cassette, and try all the controls. 
Insert a roll of silver printing paper into the printer and press the 
button on the right-hand side of the printer to feed some paper 
through. Check the paper does not rub on either side of the 
printer as it comes through. 
Press the key and then the [NEWLINE (ENTER) | key. 
The printer will start to copy what is on the screen. About 3 
inches of paper will be fed through. There will be nothing 
printed on it as there is nothing on the screen. A message 0/0 
will appear at the bottom of the screen. 

N.B. The bottom two lines of the screen are never printed 
and are used for keying in program lines and commands. These 
program lines, when correct, are transferred into an area of 


8 


memory reserved for the programs by pressing the NEWLINE 
(ENTER) key. The program lines will then appear on the 
printer when the COPY command is given. 

14 Press characters at random on the keyboard. They will appear at 
the bottom of the screen. Press and [EDIT | keys 
together to clear the screen. 

15 If the cursor will not appear on the screen switch off the 
power supply and adjust the 16k RAM pack and printer 
connections. Switch on the power supply again and retune the 
TV. 

N.B. Never adjust or pull out the RAM pack when the power 
supply is ON, you may damage it. 

16 Other components failing to work will probably be caused by 
plugs not switched on, or fuses blown. Alternatively, it could be 
that some connections are not being properly made. You should 
remove and re-insert Jack-plugs and connectors. 

17 On leaving your computer: 

a Leave it connected up 
b Switch OFF a.c. power supply plugs and TV 


c Disconnect plugs from sockets. 


B2: The Keyboard 


The ZX81 keyboard has 40 touch sensitive keys arranged in 4 
rows of 10 keys. 


At first sight it looks like a typewriter keyboard, but a closer look 
reveals that some keys have five functions or characters written on 
them. In fact: 


Six different characters can be obtained from some keys! 
The keyboard contains: 


(1) The digits 0 to 9 
(2) The letters of the alphabet printed in upper case 
(3) The complete BASIC language 
— instructions 
— commands 
— arithmetic, conditional and logical operators 
— arithmetic functions 
(4) Grammatical signs and symbols 
(5) Special control keys 
(6) Graphics symbols 


These are all called characters. 
Notice that words like PRINT, RUN, SLOW, LET, INKEY$ are 


9 


written on the keys and are printed on the screen when we press that key 
in the correct mode. 

The facility of complete words in the BASIC language being printed 
at the press of a single key is called 


SINGLE KEYSTROKE BASIC 


On most other computers you have to key in each letter of, for 
example, the instruction PRINT. This is inefficient. The ZX81 is very 
powerful in this respect. 

The keyboard contains most of the characters in the ZX81 character 
set and a few special keys. Some 202 different characters are available. 
Some print on the screen, others are non-printing, e.g. RUBOUT 
(DELETE). 

Each of the different types of character 1s described in Section B4. 

The ZX81 keyboard layout is reproduced in the diagram on the next 


page. 
B3: Cursors 


is] [>] 


Cursors indicate what operational mode the computer is in and what 
symbol or name should be typed in next. They appear in inverse video 
(a white letter in a black square). 


Keyword mode. 


ZX81 expects a command 
a line number 
or a keyword 
Keywords are the symbols printed on the keyboard 
above the keys (see keyboard). SHIFTed keys also 


function in this mode. 


Letter mode. 


Occurs at most other times. 
ZX81 expectsa letter 
a number 


an operator 


ora special command 
SHIFTed keys function in this mode. 


Function mode. 


Obtained by pressing FUNCTION key (SHIFT, 


NEWLINE/ENTER). 
The functions obtainable are printed under each key 


in white. 


10 





Figure 2 
ZX81 KEYBOARD 


ГЫ 86791 s e Se a e 
M 


CODE PEEK 


IT 


ap ж 


JE es DS Mei ш ч" 
AG БЕЙ K [ENTER] 


ARCSIN = Ж: DS 


COPY CLEAR fis 


Only one function can be obtained each time 
FUNCTION is pressed. 


Graphics mode. 


Obtained by pressing GRAPHICS key (SHIFT, 9). 
Mode lasts until the GRAPHICS key is pressed again. 
In the graphics mode 36 different characters are 
obtained by pressing the keys with the SHIFT key 
depressed as well. These are shifted graphics characters. 
38 different characters (mainly letters printed in the 
inverse mode) are obtained by pressing the keys. 


[s | Syntax error cursor. 
This cursor appears in a statement line at the bottom of 
the screen if the computer finds that there is an error in 
it. It appears when we try to enter an incorrect line of 
program into memory (i.e. after we press NEWLINE 
(ENTER) when at the bottom of the screen). 

The [S | cursor appears next to the last error in the 
line. (There can be more than one). Editing on the line 
сап take place immediately. The [5 | cursor disappears 
when an edit operation is performed. It will re-appear 
(if necessary) when NEWLINE (ENTER) is pressed 
again. 


Current line cursor. 


When entering statements into the program the last line 
to be entered is called the current line and is indicated 
by this symbol placed after the line number. The 
movement of this cursor up and down the screen, 
pointing to different lines, is controlled by the { and 
^ keys (SHIFT 6 and 7). 

If EDIT (SHIFT 1) is pressed, the current line is 
brought down to the bottom of the screen and can be 
edited. 


B4: The Different Character Types 
THE 6 CHARACTER TYPES ON A KEY 


If we examine a particular key, say [R ] , we can classify the 6 character 
types, as seen in the diagram below. 








RUN 








LETTER 





<= 






ec 

= 
INVERSE GRAPHICS 
GRAPHIC 


INT - 






KEYWORD 


On top of the R key is the word RUN. This is a KEYWORD 


character. 


All characters printed on the keyboard in this position are 
KEYWORDS. KEYWORDS will be printed on the screen if the 
desired key is pressed when the ZX81 is in KEYWORD MODE (1.е. 
the cursor is on the screen). 


Exercise 


If the | К | cursor is at the bottom left-hand side of the screen then enter 
a keyword. Press the | PRINT | (P) key. Notice that PRINT appears on 
the screen but the cursor has changed to an cursor and the 
computer is in the letter mode. This means that it 1s expecting a letter 


to be keyed in next, e.g. A. 
If we try to key in another keyword, e.g. , the keyword 
PLOT does not appear. Instead the letter O is printed. So the rule is: 


No two keywords may be entered in succession. 


To clear the screen and return to mode press 


keys together. Try it. Print different keywords on the screen. Which 
one does not print? 


LETTER 


The LETTER characters (or OWERTY characters as they are 
sometimes called) are the bold type letters on each key. They are 
identical to those on a typewriter keyboard. It is worth trying to 
memorise these. Do it by lines, and in groups of five. 

Letter characters may be keyed in when the computer is in the letter 
mode and the cursor appears in the entered program line, or at the 
bottom left-hand side of the screen. Certain letters may be entered in 
the mode as default when there is no keyword on that key, e.g. the 
digits 0-9 and the full stop[ e] [BREAK] is also an exception. A space 
Is printed in the mode. 


13 


Exercise 


Key in | PRINT | to obtain the mode. Then key in the letters, 


starting from [1]. 


What happens with | NEWLINE (ENTER)| and |SPACE |? 


SHIFT 


There are 39 SHIFT characters on the keyboard. These may be 
obtained in the Or modes, 1.e. when Or is on the 


screen. 
To obtain these characters or symbols e.g. in our diagram, 
press the | SHIFT | key and the desired | CHARACTER | key at the 


same time. 


Exercise 


Start keying in the SHIFT characters starting with on the top 
line of the keyboard. 
Notice what happens with: 
EDIT 
THE ARROW KEYS (^4 | e>) 
GRAPHICS 
RUBOUT (DELETE) 
FUNCTION 


GRAPHICS 


There are two types of graphics characters, the characters like Bll as in 
our diagram below, and the letter and shift characters printed in 


INVERSE (i.e. white letter on black background) on the screen ( Ia). 


Exercise 


To print the graphics characters on the screen key in: 


14 


Keys to Press What happens on the Screen 


PRINT 


E] PRINT 
PRINT 
ГЕ | PRINT 
[К | PRINT 
PRINT 
[Эй] PRINT 


NEWLINE (ENTER) ББЗ at top of screen 


0/0 at bottom of screen 


NEWLINE (ENTER) [3 (clears screen) 





Notice the mode cursor changes. 

Note that to come out of the mode, you need to press 
again, to get the cursor back. To clear the screen 
press | 


Repeat the exercise and obtain all the graphics characters. Where no 
graphics character is printed on the key then the inverse of the shift 
character is obtained by default. ‘Test this out. 


INVERSE GRAPHICS 


These characters are the inverse video letter characters, and are 
obtained in the GRAPHICS mode, i.e. cursor on the screen, when 
the desired key is pressed. 


Exercise 


Key in the characters as before, but this time only press the letters and 


not the shift characters when in the mode. 
What happens when you press |SPACE] ? 


FUNCTION 


There are 24 Function characters that are obtained only in the 
Function mode, when the [F ] cursor is on the screen. The ГЕ |cursor is 


obtained by pressing the |SHIFT | and | FUNCTION | keys together. 


Only one Function character may be entered. The mode changes to 
after entry. To input another Function character we need to get 
back to the mode again. 


Exercise 


Get into the FUNCTION mode and key in all the function characters. 
Key in - 
Lr] 


What happens? Press NEWLINE (ENTER) again to clear the screen. 


HOW TO OBTAIN THE DIFFERENT CHARACTER TYPES 
Character Number of To Obtain | To Obtain the 
Type Chars. the Mode: | Character: 
mmm f 26 | [E] | лонае 

SHIFT 39 [K ] Automatic SHIFT 
CHARACTER 
LETTER 39 
Automatic CHARACTER 
K] 
(sometimes) 
mt = = 


GRAPHICS CHARACTER 
INVERSE 


GRAPHICS 


Е 




































GRAPHICS 






CHARACTER 








SHIFT 
FUNCTION 










CHARACTER 


Exercise 


Using the above table, obtain all the modes and key in example 
character types. 


ALPHABETIC CHARACTER/KEY TABLE 


The following table locates the letter or number key which provides 
each character (keyword, function, or symbol) on the keyboard. Use 
this table when entering programs until you are familiar with the 
placing of all the commands. An * indicates a non-printing character. 


BASIC Word Keyword (K), Function 
or Shift and Key to Press 


ABS Function G LPRINT Shift S 
ACS Function S NEW (K) A 
AND Shift 2 NEXT Shift N 
ASN Function A NOT Function N 
AT Function C OR Shift W 
ATN Function D PAUSE Shift M 
CHR$ Function U PEEK Function O 
CLEAR (K) X PI (m) Function M 
CLS (K) V PLOT Function О 
CODE Function I POKE Function O 
CONT (K) C PRINT Function P 
COPY (K) Z RAND Function T 
COS Function W REM Function E 
DELETE Shift Ø * RETURN Function Y 
DIM (K) D RND Function T 
EDIT Shift 1 * RUBOUT Shift @ * 
EXP Function X RUN Shift R 
FAST Shift F SAVE Shift S 
FOR (K) F SCROLL Shift B 
FUNCTION Shift NEWLINE(ENTER) SGN Function F 
GOSUB (K) H SIN Function Q 
GOTO (K) G SLOW Shift D 
GRAPHICS Shift 9 * SOR Function H 
IF (K) U STEP Shift E 
INKEY$ Function B STOP Shift A 
INPUT (K) I STR$ Function Y 
INT Function F TAB Function P 
LEN Function K TAN Function E 
LET (K) L THEN Shift 2 
LIST (K) K TO Shift 4 
LLIST Shift G UNPLOT Function W 
LN Function Z USR Function L 
LOAD (K) J VAL Function J 


17 


SYMBOLS 
Symbol Cursor and Key Symbol Meaning 


K or L, Full stop or dec- 
imal point (Separate key) 


š K or L, shifted Full stop. Comma 

; K or L, shifted X. Semicolon 

z К or L, shifted 2. Colon 

? К or L, shifted C. Question mark 
`y K or L, shifted P. String quote 
iis K or L, shifted О. Quote image 

( K or L, shifted I. Open bracket 
) K or L, shifted O. Close bracket 
£ K or L, shifted SPACE. Pound 

$ K or L, shifted U. Dollar 

+ K or L, shifted K. Plus 

- K or L, shifted J. Minus 

7 K ог L, shifted В. Times 

/ K or L, shifted V. Divide 

те K or L, shifted Н. To power 

= K or L, shifted L. Equals 

> K or L, shifted M. Greater than 
< K or L, shifted N. Less than 

© = К or L, shifted К. Less than or equal to 
> = K or L, shifted Y. Greater than or equal to 
<> K or L, shifted T. Not equal to 
“= K or L, shifted 5. Cursor left 

{ К ог L, shifted 6. Cursor down 
T K or L, shifted 7. Cursor up 

Т” K or L, shifted 8. Cursor right 


18 


SECTION C: BASIC BASIC 


C1: The BASIC Language 


This book is all about BASIC, which is the world's most commonly 
used computer language. Just as English is a natural language used to 
communicate with people, BASIC is a formal language used to 
communicate with COMPUTERS. Like natural languages BASIC 
has grammatical rules which, although they are fairly simple, must be 
strictly followed to ensure that the computer understands exactly what 
it is being instructed to do. 

BASIC stands for Beginners All-Purpose Symbolic Instruction 
Code. It was invented in 1964 in the USA and is a combination of 
simple English and algebra. BASIC is the language we will use 
throughout this book to write PROGRAMS. Programs instruct the 
computer what to do, and the sequence in which particular operations 
are to be performed. 

BASIC is a high-level programming language. The instructions we write 
in BASIC are interpreted by a built-in program into the low-level 
programming language (the MACHINE CODE) that directly controls 
the switching of the electrical impulses inside the MICROCHIPS 
which store and manipulate the data. High-level languages like BASIC 
are far easier to write programs in than the low-level languages, and 
the simple language and structure of BASIC was designed to be easy to 
learn. The Sinclair version of BASIC also has single-keystroke entry of 
BASIC words, which makes mistakes in spelling impossible. 


C2: A Simple Program 


A sequence of BASIC statements is called a PROGRAM. Here 
is an example of a program: 


10 INPUT A 
20 INPUT B 
30 LETS=A+B 
40 PRINT S 


The simple program above adds two numbers keyed in on the 
keyboard and prints the results on the screen. A program is keyed (or 
typed or input or entered) into the computer by you, the programmer, 
line by line, from the keyboard. 

Before we key a program in we design it to make the computer do 
exactly what we want. We first write a program down line by line on a 
piece of paper. This is called CODING. 

After coding the program we key it into the computer and RUN it. 
To RUN it we give the computer a COMMAND to RUN the program 


to see if it works. It probably won't work the first time, unless it's as 


19 


simple as our example. A program which doesn’t work as intended is 
said to contain ERRORS or BUGS. 

If we have asked it to do something it can’t do, or forgotten to 
include an instruction the computer will tell us what is wrong and give 
us an ERROR MESSAGE. If the program runs without error 
messages but doesn’t do what we wanted it to then it is the 
programmers’ fault. In either case we need to correct or EDIT or 
DEBUG the program. We do this whilst the program is in the 
computer, using the editing facilities of the computer. 

Editing or revising a program is called PROGRAM 
DEVELOPMENT. When the editing is finished and the program 
works we take a LISTING of the program on the PRINTER. We can 
also SAVE a copy of our program on cassette tape and STORE it so 
that we can LOAD it back into the computer. 


The complete exercise of designing, coding, developing and 
documenting a program is called PROGRAMMING. 


C3: A Statement 


This is a BASIC statement: 
10 INPUT A 


A statement is also called a LINE. A statement can: 
(1) instruct the computer to do something 
(2) state something 
A statement is composed of: a line number, e.g. 10 
an instruction, e.g. INPUT 
some variables, e.g. A 
Statements are either: Executable — those which specify a program 
action, as with our INPUT A, or Non-Executable — those which 
provide information for the user of the program. 
All variables (e.g. A in our example) must be initialised to a start 
value before being used in a program. In this case the statement: 
10 INPUTA 
tells the computer to request the user to input a value for the variable A 
from the keyboard. 


C4: Statement Numbers 


Each BASIC statement or line must begin with a statement 
number, as with 20 in this example. 
20 INPUT B 


The number 20 is called a statement number or line number. The 
statement number is chosen by you, the programmer. It may be any 
number from 1 to 9999 inclusive. ‘The computer uses the numbers to 
keep the statements in order. Each statement has a unique statement 


20 


number. If you use the same statement number twice, the second line 
will replace the first. 

Statements may be keyed in via the keyboard in any order. The 
computer sorts them into the correct sequence. Statements are usually 
numbered in tens so that additional statements are easily inserted later. 
For example: 


10 INPUT А 

20 INPUT B 

25 INPUT C (Inserted line) 
30 LET S=A+B 


The computer runs the program in order of statement numbers. 


C5: Instructions 


A statement gives an instruction to the computer. In this 


example it is LET. 
30 LETS=A+B 


Instructions are called statement types because they identify a type of 
statement. In our example the statement is a LET statement. It tells 
the computer to let the variable S have a value equal to the sum of the 
values of variable A and variable B. 


C6: Numeric Variables 


A numeric variable is the name given to a storage location 
which holds a number in the computer's memory. 

A numeric variable can have a name which is: 

A letter from A-Z 

or A letter followed by a number 

or A group of letters and numbers 
Variable names must start with a letter. 

Examples of numeric variables: A 


NUMBER 1 


Numeric variables are used to represent numbers inside the computer. 
We can give (or assign) different values to a variable. The numbers we 
give to variables are used in calculations. 

Variables are symbols or names given to parameters or quantities. 
They represent the VALUE of the parameter, i.e. the number stored 


21 


in the named memory location. We can use variable names which 
remind us of the parameter concerned, but they should not be too long 
or you will find them tiresome to key in (which is why single letters are 
usually used). 
For example, we could use: 
S — Speed 
PRICE - Price of fish 
SUM 1 - Sum of the first set of numbers 
R3 - Resistor Three 


In our program the statement 

10 INPUT A 
sets up a variable in the computer's memory with the symbolic name 
A. We could have called it NUM1, or even FIRSTNUMBER. 

The statement tells the computer to ask us to input a value for À 
when we run the program. If we key in the number 3 the memory cell 
allocated to A will contain the number 3. This value is then used in all 
calculations involving À until we change its value. 

In the statement: 

30 LETS=A+B 

S, A and B are the variables in the algebraic equation S= A + B. Š is 
our ‘unknown’ and will take the sum of the values of A and B. The 
computer will work out the value of A + B and put the result in the 
memory cell it has allocated to the variable S. The computer will not let 
us input LET A+ B = S (it will give us a syntax error), because the 
variable to be given a value must come first. A + B is not a valid 
variable name. 

Variables are so-called because their values can vary or change, 
according to the values we input, or in the course of a program, when 
we instruct the computer to do something which causes the value to 
change. For CONSTANTS, which are quantities which do not change 
their value, we set up a variable in the same way, by giving it a name 
and a value with a LET statement and let it keep the same value — a 
variable that doesn't vary! 

Variable names may be of any length, but they must start with a 
letter, and must only contain the alphanumeric characters (the letters A 
to Z and the numbers @ to 9). They can have spaces included, but this 
is unwise, as it is easy to key іп PRICEI, for example, when you 
initialised a variable as PRICE 1. The computer will consider them to 
be two different variables. The inverse video (white on black) 
characters also cannot be used in variable names. 


22 


C7: Strings and String Variables 
STRING 


A STRING is a group of characters enclosed by quotation 
marks. 
The following are examples of strings: 


“PETER” 

“12345” 

“JANUARY 1ST, 1982” 
sot “Жы А, 


“REF:A2” 


As well as numbers, computers can also handle text or groups of 
characters. Го define a group of characters as a string, we have to place 
quotation marks at the beginning and end. This tells the computer, for 
example, that the string ‘“TOTAL’’ means the characters T,O,T,A,L, 
and not the numeric variable TOTAL, which is a number. 

Strings can contain any character which prints on the screen, plus 
spaces, but a string cannot contain quotation marks, because the 
computer thinks it has got to the end of the string when it gets to the 
second quotation mark. 

Now that you know what a string is, we can tell you that strings can 
be handled by string variables, just as numbers can be manipulated 
with numeric variables. 


STRING VARIABLE 


A string variable is used to store strings. It consists of a single 
letter (A to Z) followed by the $ sign. For example: 
A$, Z$, M$ 


We allocate (or assign) strings to string variables with LET statements, 
as with numeric variables. For example: 

10 LET A$=‘‘STRING 1" 

20 PRINT A$ 
The memory store allocated to A$ will contain the string ‘STRING 1’ 
(line 10). 

When we RUN the program the computer will print the contents of 
memory store A$ on the screen (line 20), i.e. STRING 1. Note the 
string is printed without the quotation marks. The string is just the 
characters inside the quotes. 





22 


C8: Operators and Operands 
OPERATORS 


Operators perform arithmetic, logical or conditional 
operations on variables or numbers. 
In our program the line: 
39 LETS=A+B 
uses the two arithmetic operators 
= and + 


OPERANDS 


Operands are the variables or numbers which are 
manipulated (i.e. operated on) by the operators. 


In the line: 
30 LET S=A+B 


the variables S, A and B are operands. 


C9: Format of Statements 


BASIC is a ‘free format’ language. The computer will ignore 
extra blank spaces in a statement. 
The following statements are equivalent: 


10 INPUT A 
10 INPUT A 
10 INPUT A 


The computer will automatically leave spaces after each line number 
and a space after keywords. It will list programs with all the other 
spaces you include between instructions and variables. It will ignore 
them when you run the program. 


C10: Keying in a Statement 


Statement to be keyed in: 


10 INPUTA Press 


If your computer system is set up and ready for use (see Section B1) the 
cursor will be in the bottom left-hand corner of the screen. You can 
now key in the first statement. 


24 


Character or Cursor Keys to What appears 
instruction Press on the Screen 


to key in 





[к] 
2 2 19 [к] 


ж 
INPUT I 19 INPUT 
A [z]. A i mera [Z] 
* 
NEWLINE 
(ENTER) 


Entered line is 
transferred to top 
of screen 


* 
on Spectrum in CAPS mode 


PRESS NEWLINE (ENTER) AFTER EACH STATEMENT 


The |NEWLINE (ENTER)| key must be pressed after each 


statement has been entered. 
10 INPUT A 
20 INPUT В 
30 LET S =A+B[NEWLINE (ENTER) | 
40 PRINTS 


Pressing the | NEWLINE (ENTER) | key informs the computer that the 


statement is complete. The computer checks the line for mistakes then 
transfers the statement to the top of the screen and returns the 
cursor to the left-hand side of the screen, ready for us to enter the next 
program line. 

Notice that the line at the top of the screen now contains the 
CURRENT LINE CURSOR: 
This indicates the last program line entered and accepted by the 
computer. It appears immediately after the line number: 


10 [>] INPUT A 


25 


C11: Correcting Errors 
RUBOUT (DELETE) 


The RUBOUT (DELETE) key acts as a backspace, deleting 
the character symbol or keyword immediately preceding (to 


the left of) it. 


As we type in a line we may press the wrong key. For example, we 
might get: 

10 INPUTS 
where we pressed S instead of A. To correct this we press RUBOUT 


(DELETE) and we get: 
10 INPUT 
We may now continue and type in A. 


The horizontal arrow keys move the cursor one character or 
keyword to the left or right along a line as indicated. 


For obvious reasons, these keys are also referred to as cursor control 
keys. 


To correct an earlier mistake on a line 


(a) Use the arrow keys to move the cursor to a position immediately 
to the right of the character to be changed. 

(b) Press RUBOUT (DELETE) to delete the incorrect character, 
and key in the correct character. 

(c) Use the arrow key to return the cursor to the end of the line, if 
you have more to key in. Otherwise, you may press NEWLINE 


(ENTER) immediately. It does not matter if the cursor is In 
the middle of the line. 


To delete a complete line 





This can be done by using the > key to get the cursor to the end of the 
line, if you are not there already, and then using RUBOUT 
DELETE) repeatedly until the line is completely deleted and just the 
cursor remains. This is tedious on a ZX81, without the 
Spectrum’s repeat key, especially on a long line. A better way is: 

(1) Press EDIT 

(2) Press NEWLINE (ENTER) 


26 


If you are keying in the first line of a program and there are no existing 
lines at the top of the screen, pressing EDIT will clear the line. 

If there are program lines at the top of the screen, pressing EDIT 
clears we current line and brings down the program line marked with 


the cursor. Pressing NEWLINE (ENTER) sends this line up 


again г. clears (һе current line. 
Exercises 


1 Start keying in the first line of the program. Don’t press 
NEWLINE (ENTER). 
Play around with the cursor control keys and RUBOUT 
(DELETE). 
Delete the complete line. 
3 Key in the first line and press NEWLINE (ENTER). 
Key in the second line. 
4 Delete the second line using EDIT and NEWLINE (ENTER). 
5 Кеуіп the second line. Key in the third line to read: 
30 LET X =A + B. Press NEWLINE (ENTER) 
Use EDIT to bring this line down again. Use the cursor control 
keys to put the cursor to the right of X and delete it. Insert S. 
Leave the cursor where it is, and press NEWLINE (ENTER) to 
send the line to the top of the screen. 
6 Key in the complete program. 


N 


C12: Commands 


COMMANDS are direct instructions to the computer. They 
are executed immediately. They do not need line numbers, as 
they are not part of a program. 
Commands give us direct control over the computer. 

Examples are: 

RUN 

LIST 

BREAK 

SAVE 


To execute a command, we key it in. If it is a command that is printed, 
it will appear on the bottom line of the screen. This area of the screen 
must be empty. Then press [NEWLINE (ENTER). Some commands 
are executed instantly, without pressing NEWLINE ie i (e.g. 
BREAK), and are not printed on the screen. 

Most commands are also used as instructions in programs. Some of 
the commands that can be used as direct commands are not actually 
very useful in this role. Equally, some that could be used in programs 
never are. However, each command has a key role to play in the 


27 


BASIC language and we will deal with the individual commands as we 
encounter them in the text. 

You have already met the NEWLINE (ENTER), RUBOUT 
(DELETE), < and -” commands, and the mode commands 
(GRAPHICS and FUNCTION). Together with EDIT, RUBOUT 
(DELETE) and BREAK, plus the f and $ arrow keys, these are the 
commands that don’t print, and act instantly. All the others need 


NEWLINE (ENTER) to be activated. 
C13: Editing the Program 


EDIT 


The EDIT command copies the program line indicated by the 
cursor at the top of the screen, to the bottom of the screen, 
replacing any current line. The line brought down can then 


be edited or changed. 


EDIT may also be used for entering lines that are similar where only 
the line number changes: 

(1) Key in the line. 

(2) Press NEWLINE (ENTER) - line goes to top of screen. 

(3) Press EDIT - line copied to bottom of screen. 

(4) Use RUBOUT (DELETE) to delete the line number. 

(5) Key in new line number. 

(6) Press NEWLINE (ENTER) - new line goes to top of screen. 
The same procedure can also be useful with lines which only vary 
slightly, i.e. perhaps only the line number and a variable are different. 
If you can save keystrokes by bringing down a line and revising it, then 
do so. The technique is as above, but after (5) you must use the cursor 
control keys to shift the L-cursor along the line and use RUBOUT 
(DELETE) to erase the variable (or keyword) that needs to be 
changed. Insert the new character, and press NEWLINE (ENTER). 


These commands move the cursor in the entered program 
at the top of the screen from one line to another. This enables 
us to then copy down any line in the program for editing using 


[EDIT]. 


Deleting a line in the entered program 


To delete a given program line which has been entered and is at the top 


28 


of the screen just type the line number and press NEWLINE 
(ENTER). 
For example: 


10 |NEWLINE (ENTER 


will delete line 10 in the program. You will see it disappear from the 
screen. 


C14: Listing a Program on the Screen 


LIST 


The program has been entered into memory. To produce a 
listing on the screen of all lines accepted by the computer key 


in: 
LIST NEWLINE (ENTER 


LIST is a command that prints on the screen. It appears on the bottom 
of the screen, and is executed when NEWLINE (ENTER) is pressed. 


LIST N 


Will list a program starting from program line N. 
For example, if we key in: 


LIST 30 NEWLINE (ENTER 


our program will be listed from line 30. 


We key in LIST, then the line number we want the listing to start at. If 
we have a program that is longer than will fit on the screen, we use the 
LIST (line number) command to display successive screenfuls of the 
program. If the bottom line on the first screen is 210, for example, we 
would use LIST 220 to get the next set of program lines. Listing a 
program on the Spectrum which is larger than a screenful produces a 
SCROLL? prompt. Answering this with anything other than ‘N’ or 
BREAK scrolls the listing up so that the next screenful of statements 
can be seen. 


C15: Running the Program 
Our simple program has been keyed into the computer line by line and 
entered into memory. 


Let's see if it works. We give the computer the command RUN. 


29 


RUN 
NEWLINE (ENTER 


The RUN command starts execution of a program at the 
lowest numbered statement. 


Run is a command and is keyed in. It appears at the bottom of the 
screen. It will not be executed until [NEWLINE (ENTER)] is pressed. 
When we do this the program starts operating. The screen will go 
blank and the L-cursor will appear at the bottom. (This will be a 
C-cursor if you are using a Spectrum in CAPS (capital letter) mode, 
using CAPS LOCK as we advised.) The computer is now running the 
program and asking us to input a number for the variable A. 

Key in the number and press [NEWLINE (ENTER)] . The 
L-cursor appears again at the bottom of the screen. The computer 
requests another number, to be assigned to the variable B. Key in the 
number | 5 | and press . 

Our result (the number 8) is printed at the top left of the screen. 
Notice the message that appears on the bottom of the screen. We can 
also run the program from a line other than the first program line: 


RUN N 


RUN (Line Number) 
This command starts execution of the program from the 
specified statement (line) number. 
RUN 20 
will start a program at line 20. 


Note that when the RUN N command is used all statements before the 
specified statement number (N) will be ignored and any variables 
defined in these statements will be considered by the computer to be 
undefined because it has not RUN the lines. The program will not 
work and an error message will result. All values of variables are 
wiped out by the RUN command. 

We can RUN the program as many times as we wish: 


Key in [| NEWLINE (ENTER) | again 


If the program has been run once and the message is at the bottom of 
the screen, to rerun the program key in RUN. This overwrites the 
message and pressing NEWLINE (ENTER) starts the computer 
operating the program. The L-cursor appears to prompt for an input 
again (C-cursor for Spectrum in CAPS mode). 


30 


The screen is now blank. We can get the program listing back very 
easily: 


Press NEWLINE (ENTER) 


After running the program, the program listing re-appears at the top of 
the screen if the NEWLINE (ENTER) key is pressed. The program 


can now be edited if necessary. 
C16: Error Messages 


Our computer tells us it has finished running the program by giving us 


a message. On the ZX81 this will be: 
0/40 


at the bottom of the screen. The Spectrum gives an expanded version 
of the message: 


0 OK, 40:1 


This tells us that no errors were found and the program finished at line 
40 (the last line). The number after the colon can be ignored in most 
Spectrum error messages, as it refers to multiple-statement lines. We 
shall not use these in this text. There is one case where it is 2, as we 
shall see later. 

These special diagnostic messages appear at the bottom of the screen 
every time a program is run. If the program does not work a message 
appears with the form: 


E/N 


E is a number or a letter indicating the type of error that has caused the 
program to stop, and N the line number where the program halted due 
to the error. The Spectrum adds a message briefly stating the cause of 
the error. 

We look up the meaning of E in the list of Error Codes in Appendix 
II. This helps us to correct or debug the program, since we know what 
sort of problem has occurred and which program line it happened at. 


Exercises 


1 Run the program on page 19 a number of times keying in 
different values for A and B. 
2 Press NEWLINE (ENTER) to get the listing. Change line 30 to 
read: 
30 LETS-A-«C 


31 


Now RUN the program. 

The error message 2/30 (on the ZX81) appears. On the 
Spectrum we get 2: Variable not found 30;1. So we have a type 
2 error and the program stopped at line 30. A type 2 error means 
we have forgotten to define a variable. We are now using the 
variable C instead of B, but we have not yet given C a value, and 
the computer could not complete the operation of line 30 due to 


insufficient information. 
Insert a new line: 


25 INPUT C 
and run the program again. It now works. 


Why did the program originally stop at line 30? 
Why do we now have to key in 3 numbers to make it work? 
3 Add an extra line at the beginning of the program. Key in: 
5 PRINT “PROGRAM ADDS 2 NUMBERS" 
RUN the program, starting from different lines by using: 


RUN 
RUN 10 
RUN 15 
Why do you think RUN 15 does not work? 


4 Edit the program to obtain the original version. 


C17: How the Program Works 


Line 10 tells the computer that a number must be 
input and given the name A, (i.e. assigned to the 
variable A). ‘The computer reads the line and prints 
an at the bottom of the screen,* reminding us 
to input a number. The computer will wait until we 
key in a number. The number is then stored in 
memory cell A. The computer goes to the next line. 

Line 20 tells the computer that another number, 
to be assigned to the variable B, must be input. 
appears at the bottom of the screen* and the 
computer waits until we key in a second number, 
which is stored in memory cell B. The computer 
goes to the next line. 

Line 30 tells the computer that a variable 5 18 to 
be assigned the value of the sum of the variables A 
and B. The numbers in cells A and B are added 


10 INPUT A 


20 INPUT B 


30 LETS=A+B 


*This will be a C-cursor if using a Spectrum with the CAPS LOCK facility used, as 


Spectrum users must do throughout this text to get program listings which appear the 
same as the ones in the text. Use the CAPS SHIFT and CAPS LOCK keys 


simultaneously on switch-on, and remember that the C-cursor will appear instead of 


the L-cursor. We will not mention this again. 


32 


and placed in cell S. The computer goes to the next 
line. 

Line 40 instructs the computer to output the 40 PRINT S 
value of Š to the screen. The computer looks for the 
next line. 

The computer can find no more statements to 
execute in the program and gives a message 0/40 
on the screen telling us that the program finished 
with zero errors at line 40. The Spectrum gives the 
same message, in the form 0 OK, 40:1. 

The computer now waits for more commands. 


C18: Naming the Program 


5 REM “NAME” 
Programs are named in a REM statement. The program name 
is enclosed in quotation marks. The program is usually named 
in the first statement in the program. 


We need to give our program a name in order to: 

(1) Differentiate it from other programs 

(2) Store it permanently on cassette tape (SAVE it) 

(3) Put it back into the computer from cassette tape in order to run it 

(LOAD it). 
The program name can be any combination of characters and any 
length on the ZX81. On the Spectrum, program names for use with the 
SAVE and LOAD instructions must start with a letter, and can only 
have 10 characters in the name. 
It is sensible to keep the program name short and relevant to the type 

of program, although some programmers name programs after 


themselves: 
“PETER 1” 


“PETER 2" ete. 
Programs which undertake various kinds of statistical analysis could be 
named: 
"STATS 
“STATS2” etc, 
Programs which perform calculations for experiments in the laboratory 
could be named: 
"OPTICS З” 
“FRICTION” 
“TITRATION” etc. 
If spaces are used in program names, it is easy to misread them, or 
forget that there should be a space. If the program name is not one 
word, we can use an asterisk: 
“FETTER?” 
“FOCALLENGTH” etc. ((FOCAL*LEN"' for the Spectrum) 


33 


Program names and cassette tape codes should be recorded in a 
DIRECTORY which enables us to access a PROGRAM LIBRARY 
of programs stored on tape. 
We need to name our program: List the program and add a line 
which names the program. For example: 
5 КЕМ “SUMPROG” 
or S REM “PROGI” 
could be used. We will call our program “АПОПОЕК”, so key in 
5 REM “ADDER” 


34 


SECTION D: SAVING, LOADING AND LISTING 


D1: Saving the Program on Cassette Tape 


We need to save programs on to cassette tape (the off-line storage medium 
the Sinclair computers use) because when the power supply is switched 
off (or disrupted - variations in the mains supply can affect the 
computer) the RAM memory and the registers in the CPU are cleared 
and we lose the program. The memory is said to be volatile. This means 
we have to key it in again — not too bad for a 5 line program, but a 50 
liner will take you an hour! 

If we had made a copy of the program on to magnetic cassette tape 
using the SAVE command we could have reloaded it into the computer 
quickly, using the LOAD command. Tape storage is not the quickest 
or most reliable method used for off-line storage, but it works, and has 
the advantage of low cost. The ZX81 reads and writes tape fairly slowly 
in computer terms, and a large program will take some minutes to 
LOAD or SAVE. The Spectrum loads programs several times faster. 
Software (programs) stored on tape is available for use when needed, 
making it PERMANENT. 

Software also has to be PORTABLE. Programs we write can be 
used by other people with the same computer, or software available on 
cassette can be bought. 


SAVE 


SAVE “NAME” 
The SAVE command outputs the program and variables to 
the cassette recorder. If the cassette recorder is in record mode 
then a copy of the program will be made on the tape. 


Spectrum users please note that the program name for SAVEing must 
be 10 letters or less. The name can be in either upper or lower case (or 
a mixture) but exactly the same name must be used to LOAD. It is 
safer to choose to use capitals only. 


SAVING THE PROGRAM 


1 Check that the cassette recorder is plugged in (or has 
good batteries). 

2 Ensure it is connected to the computer, with the MIC- 
MIC sockets being connected. See the important 
Spectrum note below. 


35 


мы GO 


Set the TONE control on the cassette recorder to HIGH. 
Set the volume control on the cassette recorder to 3/4 of 
MAXIMUM. 

Insert a new C12 computer cassette tape into the 
recorder. Short cassettes are more convenient than long 
ones for our purposes. 

Run the tape through on FAST FORWARD and then 
REWIND to ensure equal tension. 

Set the tape counter to zero and run the tape forward five 
revolutions (about 20 or 30 seconds). 

List the program on the screen and printer. 

Check the program is named (e.g. ‘‘ADDER’’) іп a REM 


statement. 


ZX81 Sequence 


10 


11 
12 
13 


14 
15 


Type SAVE “ADDER” don't press NEWLINE 

(ENTER) yet. 

Press RECORD and PLAY buttons on the recorder. 

Press [NEWLINE (ENTER) ]. 

Watch the screen. 

a) For five seconds it will be grey inversed by diagonal 
white lines and if the sound on the TV is turned up 
it will be a monotone. 

This is the SILENT LEAD IN 

b) For ten seconds a horizontal striped pattern appears 
on the screen. This is the program going in. A 
warbling sound is first heard, then half second 
pulses. 

с) Тһе screen goes white and the message 0/0 appears, 
telling us the computer has transmitted the program 
to the cassette recorder. 

The ZX81 does not know whether the recording is 
successful. 

We can only tell by later loading the program back 
in. 

Stop the recorder 

Note the counter reading at the end of the program. 

Run the tape forward five more revolutions of the 

counter, ready for the next program. 


Spectrum Sequence 


IMPORTANT NOTE: YOU MUST ALWAYS TAKE THE 
JACK-PLUG OUT OF THE EAR SOCKET OF THE 
SPECTRUM BEFORE ATTEMPTING TO SAVE A 
PROGRAM. 


36 


10 Key in SAVE “ADDER”. 

11 Press ENTER. The Spectrum will print a message on the 
screen which tells you to ‘Start tape’, i.e. press RECORD 
(or record and play, depending on your cassette 
recorder), and “then press any key'. Do so. 

12 Blue and red lines (black and grey оп a black and white 
TV) will scroll up the border area of your TV screen. This 
happens twice as the name of the program is recorded. 
When the program is copied, narrow yellow and 
blue/black lines roll up the border area. When the 
recording is complete an *0 OK" report appears on the 
screen. Stop the recorder. Note the tape counter reading. 
Your program should now be correctly recorded. 

13 On the Spectrum, you can check this without wiping out 
the program in memory first. Connect the EAR lead from 
the Spectrum to the cassette player EAR socket. Rewind 
the cassette to before the start of your recorded program. 
Get into the E mode, and key in VERIFY, then enter the 
program name between quotes. Press ENTER and start 
the cassette on PLAY. The Spectrum displays on the 
screen any other programs before the specified one that it 
finds on the tape, printing their names on the screen. 

14 When the program has finished playing back, an “0 OK’ 
message means the program was correctly SAVEd, and 
*R Tape loading error' means the recording is faulty and 
you should SAVE the program again. 

15 Run the cassette on five more revolutions of the tape 
counter, ready for the next program. 


The sequence above assumes a tape counter on your cassette recorder. 
Without a counter, the process of finding a program is more difficult. 
To place a voice message on the tape, so that the tape is searched for 
the voice giving the program name, will prevent the tape being 
searched automatically by the computer, but it 1s one possible method. 
If used, you should record your voice (most cassette machines have a 
built-in microphone) stating the program name several times, then the 
program name should be spelt out, the name stated again, and some 
cue statement (“saving starts now’) to let you know that after that point 
only computer-generated noises exist. This will make finding the 
program much easier, as the voice cues occupy a larger length of tape 
than a single statement of program name. 

The other alternatives are to place only one program on each tape (a 
bit uneconomical!) or to leave very large gaps between tapes (30 
seconds at least), so that you can search using fast forward/reverse and 
are unlikely to miss the gap. This has the advantage that you can set 
the computer to search through the tape program by program if you do 
miss it. Larger programs should be placed if possible on a side of a 


37 


cassette by themselves. Short length cassettes are available (5 minutes a 
side) to make this a viable option. 


Exercises 


1 Try a dummy run first. Do not press the recorder keys. Turn up 
the sound on the ТУ until you can hear a hum. Awful, isn’t it! 
Key in SAVE “ADDER?” and press NEWLINE (ENTER). 
(Press a key in response to the message if using a Spectrum). 
Watch the screen and listen to the different sounds. When the 
screen clears and the 0/0 message appears (0 ОК, 0:1 оп а 
Spectrum), key in LIST NEWLINE (ENTER) to get the listing 
back. 

2 Now SAVE the program on to the tape. 


D2: Deleting the Program from Memory 


A sure way is to switch off the power - this is not recommended. This 
should only be done if the computer needs to be re-set because it will not 
respond to commands keyed in. It is much better to use the command 
NEW. 


NEW 


The NEW command deletes any current program and 
variables from the computer and clears the screen. 


We use the NEW command before we LOAD a program into the 
computer from cassette tape, to erase old programs and data from 
memory. It is also used to do the same thing, if we have a program in 
the computer and wish to clear it out to enter another. 

There is another command that only affects the variables store, and 
not both this store and the program store, as NEW does. 


CLEAR 


The CLEAR command erases all the variables in the current 
memory. 


CLEAR can be used as an instruction in a program, as can NEW, but 
since NEW would merely wipe the program its use would be self- 
defeating. Try it, if you like the idea of a program that self-destructs! 


38 


CLEAR is similarly useless in the middle of a program - we would 
merely have to re-define all variables. 

With our program, if we RUN it, at the end of the run it will have in 
the variables store the values of A, B and S. If we then SAVE it, these 
values are SAV Ed also. In our case this is irrelevant, since the INPUTSs 
will change them when it is used but often it is useful. We can store 
data as variables in a program, and not have to re-input values (as long 
as certain procedures are followed, as we will see later). This enables us 
to have, for example, a telephone directory stored in variables. We 
might then use CLEAR to wipe one list, and re-input new data or use 
CLEAR before SAV Eing the program to send to a friend for his use. 
CLEAR acts slightly differently on the Spectrum (see page 458), but 
for our purposes at this point the difference is insignificant. The major 
function is the same. It is very easy to key CLEAR by accident on the 
Spectrum, so be careful! 


Exercises 


1 RUN “ADDER”. Enter NEWLINE (ENTER)| to clear 


the screen. Enter GOTO 40, then press NEWLINE (ENTER). 
The computer will print the value of 5. Now enter 
and then GOTO 40 (NEWLINE/ 
ENTER) again. We then get an error message 2/40 (2 variable 
not found, 40:1 on the Spectrum) indicating an undefined 
variable, because the computer has wiped the value of S. We will 


deal with GOTO in due course. Just follow the instructions for 
now. 


2 LIST the program ‘‘ADDER”’ on the screen. Press and 
. The listing will disappear and the 
cursor appears. On the Spectrum, when NEW is followed by 
ENTER, the screen will go black for a moment then become 
white, with the words ‘© 1982 Sinclair Research Ltd’ at the 
bottom of the screen. 

3. Press and then [NEWLINE (ENTER) ]. What happens? 
Why? 

4 Key in the first line of the program and press NEWLINE 
(ENTER). Switch off the power supply (by pulling out the jack- 
plug). Switch it on again (by re-inserting the jack-plug). What 
happens? 

5 Re-enter ‘‘ADDER’’. 


D-3 


39 


D3: Loading the Program from Cassette Tape 


LOAD “NAME” 


The command LOAD “МАМЕ” waits for the cassette to play 
the portion of tape with the program called “NAME” and 
copies the program, with its variables into the computer’s 
memory. 


This means that we can start the tape, give the command LOAD 
“МАМЕ”, and the computer loads nothing into its memory until the 
signal it recognises as NAME appears on tape. We can thus search a 
tape for a program. The Spectrum will print on the screen the names of 
any programs it finds on tape, before it encounters the specified 


program. 


LOAD “” 


The LOAD “” (nothing between the quotes) command 
LOADS the first program it finds on the tape. 


N 


LOADING PROCEDURE ON THE 4Х81 


Place the tape with the desired program in the cassette 
player. 

Position the tape via the counter to just before the 
location of the required program. 

Clear the computer’s memory using the 
command if there’s a program in memory. 

Set the TONE control on the tape recorder to nearly 
Maximum (High), and the VOLUME control to % 
Maximum. 

Key in LOAD “ADDER” or the appropriate name. 
Don’t press NEWLINE (ENTER). 

Depress the PLAY key on the cassette recorder. 

Press NEWLINE (ENTER). 

A thin diagonal pattern will appear on the screen with a 
single tone sound. 

The pattern changes to broad horizontal stripes with 
thinner diagonal stripes and half second sound pulses are 
heard as the program is loaded in. 

The screen clears and а 0/0 message indicates the 
loading is a success. 

STOP the recorder. 


40 


10 
11 


COND л 


10 
11 
12 


LIST and RUN the program. 
Remove the tape when finished. 


LOADING PROCEDURE ON THE SPECTRUM 


Place the tape with the desired program in the cassette 
player. 
Position the tape via the counter to just before the 
location of the required program. 
Clear the computer’s memory using the NEW command 
if there’s a program in memory. 
Set the TONE control on the tape recorder to nearly 
MAX (High), and the VOLUME control to % MAX. 
Key in LOAD ‘‘ADDER’’, but don’t press ENTER yet. 
Press the PLAY button on your cassette recorder. 
Press ENTER. 
When the Spectrum has found a program it will scroll 
blue and red bands of colour up the border area. The 
name of the program will be printed to the screen and 
then the blue and red lines repeated again. If the correct 
program has been located, then it will LOAD with a finer 
set of blue and yellow lines scrolling up the border area. 
If not, the border area will flash blue and red alternately 
as it carries on to the next program on the tape. 
When the program is correctly loaded, the phrase: 

0 OK, 0:1 
will appear at the bottom of the screen to indicate that all 
is well. 
Stop the recorder. 
LIST and RUN the program. 
Remove the tape when finished. 


CAUSES OF FAILURE TO LOAD 


1 


3 


Volume too low. 
Volume too high. 
Tone too low. 

These indicate that the program has been played at the wrong 
settings. New volume and tone adjustments will have to be 
made. Some indications of these problems are visible on the 
screen display of the ZX81, although systems vary in their 
response. Appendix IV has a procedure for adjusting tone and 
volume settings for the ZX81, as well as some general hints on 
tape use. Experiment and get to know the patterns produced 
during LOAD on your ZX81. 


41 


4 Loading started in the middle of the program. If a mistake has 
been made with the start position, rewind the tape completely 
and let the computer search for the program name. 

5 The program is not on the tape. Check your directory, and the 
writing on the cassette. 

6 Тһе program name is incorrect. Try again, making sure you 
have spelt it correctly in the LOAD instruction. If you fail again, 
run through the tape using the LOAD ““””' command. This will 
load the first program each time. Stop the cassette player after 
each load and LIST the program to check. (This is not necessary 
on the Spectrum.) If it's not the program you want, repeat for 
the next program on the tape. The Spectrum will print the name 
of all programs оп tape if you use a LOAD “ZZZ” instruction, 
i.e. a name that does not exist as a program name. 

7 Pick up from stray electromagnetic fields. 

This will show as violent interference on the screen, distorting 
the patterns together with excessive hum on the sound. It could 
originate from the ГУ itself, feedback between the recorder and 
the computer or an external field. Switch off any radio that is in 
the vicinity. Take out the jack-plug from the MIC socket of the 
cassette player, as this will break the feedback loop that can exist 
between the computer and the cassette player. 


The Spectrum has fewer LOADing problems than the ZX81. It will 
accept a much greater variation in both the volume and tone of the 
signal. However, it is worth noting that if there are great differences 
between the recorder the tape was recorded on and the one it is played 
back on (variations in tape-head azimuth is often the main source of the 
problem), then LOADing can be almost impossible, even on the 
Spectrum. 

As we noted at the beginning of the book, the Spectrum, unlike the 
ZX81, offers a choice of upper and lower case letters. Ensure that if 
you have used lower case ones in the program's name, then you use 
them again in the LOAD “ххх” command. The same applies if you 
use upper case letters to name a program. Thus, a program named 
“MATHS” will not LOAD with the statement: LOAD ‘‘maths’’. 

Some further information concerning the use of cassette tapes, and 
advice for the ZX81 if problems are encountered is given in Appendix 


IV. 
Exercises 


1 Load the program “ADDER”. LIST and RUN it. 
Delete it from memory, using NEW. 
Try loading it with different volume and tone setting. 
Estimate the volume and tone ranges for which it will not load. If 
you have a ZX81, you can do this by watching how the screen 


42 


patterns change when you change the settings while the program 
is loading. Read Appendix IV. 


D4: Listing the Program on the Printer 


LLIST 


LLIST lists the program currently in the computer memory 
on the printer, starting from the first program line. 


LLIST N 


LLIST N lists the program on the printer starting from line 
N. 


We can stop the listing by pressing (BREAK needs CAPS 
SHIFT on the Spectrum). This stops the listing with an error message 
D/line number on the ZX81 and D BREAK - CONT repeats 0:1 on 
the Spectrum. 

It is important that you keep a listing or printed record of all the 
programs you write or use. The listings are a great help in debugging 
programs (both under development and if there are problems 
discovered later). We can key the program back in from this listing, if 
necessary. 

Printouts also form part of the documentation for a program and 
should be pasted into a notebook. Printed records of program results 
can also be kept using the COPY command. 


Exercises 


1 LLIST the program ‘‘ADDER”’ on the printer. 

2 ‘Try stopping the listing with the BREAK key. The listing cannot 
be continued by pressing CONT (try it). On the Spectrum, 
despite what it says, this doesn't work. The screen just goes 
blank. Don't worry. Press BREAK again. 

3 List the program on the screen. Use the COPY command to list 
the program on the printer. 

What is the difference between the two listings obtained with 
LLIST and COPY? 


43 


D5: Program Libraries and Directories 


LIBRARY 


A collection of programs stored on cassette tape. For example: 
COMPUTERLAB PROGRAM LIBRARY 
or Your own program library. 


Notice that programs can also be stored on magnetic discs and im 


ROM memories. 


DIRECTORY 


The list of program names in the library together with 
important information about them. Another name for a 


directory is CATALOG. 


You should keep, in your notebook, or a special book, a directory of all 
programs you have entered and saved on tape. This will seem a bit 
pointless when you only have a dozen or so, but you will appreciate the 
need to be systematic when you accumulate a large number. 


PROGRAMS YOU WRITE 


Each program you write should be 

Named. 

Saved on a cassette tape. 

Listed on the printer. 

Documented. 

Catalogued into the Directory of your own program 


library. 


Gm wm G3 N = 


DOCUMENTATION 


The complete collection of information about the program or 
file, written on paper. The information should include: 
1 What the program does. 
How it does it. 
A listing. 
A flowchart. 
How to use it. 
When it was written and by whom. 


Q3 Gr мы CS N 


44 


We will introduce flowcharts in Section G. 


DIRECTORY LAYOUT 


A typical layout for the Directory Section of your notebook 
would be: 


Program Name: MOONLANDER 

Cassette Name: GAMES 3 

Locatton: 100-120 

Program Length: 30 lines 

Date Created: 18.5.82 

Author: PAUL NIXON 

Function: Lands a spaceship on 
the moon 


WRITING ON THE CASSETTE 


There is a label on each side of the cassette. Write on each 


side: 
1) Cassette name or code. 
2) Date. 


3) Program names as they are copied into it. Make sure 
these are correctly spelt! 

Your directory should provide you with the more detailed 

information, such as precisely where the program is to be 

found. 


45 


SECTION F: IMPROVING THE PROGRAM 


E1: Adding Comments 


REM 


The REM statement is used for adding comments to a 
program. All REM statements are ignored by the computer 
when the program is RUN. 

These comment statements are for the users’ benefit only. 
They contain information in the text of the program which 
explains what the program is doing. For example: 

REM **THIS PROGRAM ADDS TWO NUMBERS 

KEYED IN AND PRINTS THE RESULTS** 

Notice the use of the asterisks to separate the text from the 
instruction. 


100 REM ** END OF PROGRAM** 


The complete program including all REM statements appears on the 
screen or printer when using the LIST and LLIST commands. 


Our saved program so far looks like this: 
5 REM “ADDER” 


10 INPUTA 
20 INPUT B 
30 LET S=A+B 
4) PRINTS 


Let us add some additional REM statements: 
6 REM **THIS PROGRAM ADDS TWO NUMBERS 
KEYED IN AND PRINTS THE RESULT** 
60 REM **END OF PROGRAM** 

Key these extra statements in. LIST the program and RUN the 
program. 

Do not worry about the line numbers not being in intervals of 10. 
We will renumber the program when we have added all the extra lines. 


E2: Using the Print Statement 
PRINT 


In our simple program we will use the PRINT statement: 
a) To print messages and instructions to the user on the 
screen: 
7 PRINT “INPUT TWO NUMBERS" 
The message INPUT TWO NUMBERS is a string, and 
will be printed without the quotes. 


46 


b) To print the numbers keyed in and the result: 
40 PRINT A; ‘‘ + ’’;B;‘* = ?°;5 
A and B are the names of the variables to which the 
numbers keyed in are assigned, and S is the variable that 
stores the sum of A and B, i.e. the result. Variables do 
not need quotes to be printed. 

The semicolons (;) tell the computer that we want close 
printing, with each print item (character or variable) 
directly after the last, with no spaces between. The 
inverted commas (quotes) enclosing the symbols + and 
= means we want those symbols printed. 

c) To leave spaces between lines printed on the screen: 

8 PRINT 
The PRINT instruction used on its own prints an empty line 
on the screen. 


Note that we have changed line 40 from what it was previously. Our 
program now looks like this: 


5 КЕМ “ADDER” 

6 REM **THIS PROGRAM ADDS TWO NUMBERS 
KEYED IN AND PRINTS THE RESULT** 

7 PRINT “INPUT TWO NUMBERS” 


8 PRINT 

10 INPUT A 

20 INPUT B 

30 LET S=A+B 

40 PRINT А‘ + ‘В; = > 58 


60 REM **END OF PROGRAM** 
Key in the new lines and RUN it. 


E3: Adding a Loop 


GOTO N 


The statement GOTO N transfers program execution to the 
specified line number, N. For example: 


50 GOTO 7 


When we insert line 50 into our program we can see that, after printing 
the result on the screen, line 50 sends the computer back to line 7 to 
execute the program again from that line, and as soon as the computer 
reaches line 50 again it is sent back to line 7 once more. 

We have constructed a LOOP. The program is going to carry on 
looping forever unless we can pull out of it. 


47 


Our program now is: 
5 REM “ADDER” 
6 REM **THIS PROGRAM ADDS TWO NUMBERS 
KEYED IN AND PRINTS THE RESULT** 
7 PRINT “INPUT TWO NUMBERS” 
8 PRINT 
10 INPUT A 
20 INPUT B 
30 LETS-A-«B 
40 PRINT A;" &'B;"UeCUNS 
50 GOTO 7 
60 REM **END OF PROGRAM** 
Key in line 50. RUN the program. When you are tired of inputting 
numbers, read on. 


E4: Stopping the Program 


We need to know how to get out of the input loop between lines 7 and 
50. The program will wait for an input of a number at line 10 INPUT 
A. The cursor will appear on the screen. 

To pull out or stop the program at this stage key in [STOP | 


[NEWLINE (ENTER)]. STOP is a command we input directly, like 
RUN. 


STOP 


On the ZX81 the STOP command stops a program with the 
message: D/line number, and on the Spectrum we get H 
STOP in INPUT (Line number):1. 

The line number refers to the program line the computer 
was executing when it was stopped. 


Our program will give D/10 as the message (H STOP in INPUT 10:1 
on the Spectrum). We can cancel the STOP command and continue 
the program with the CONT command. 


CONT 


The CONT command used after the STOP command will 
continue the program from the line the program was stopped 
at. 


48 


Keyin ICONT | INEWLINE(ENTER)| to continue the program. Note 


the Spectrum prints CONT in full as CONTINUE. 
Exercise 


Run the program “АОПЕК”. 

STOP the program when the first | L | cursor appears. 

CONTinue the program, and input a value for A. 

STOP the program when the second cursor appears. Note that 
the line number is different in the message that appears on the bottom 
of the screen. 

CONTinue the program. 


E5: Testing for a Condition 


In a program we can make decisions which will affect what the 
computer does next. A decision is made on the basis of whether a 


CONDITION is true or false. 


CONDITION 


A condition has the form (X) (condition) (Y) where X and Y 
are numbers, variables or expressions and the condition is a 


conditional operator. We shall use only the = (equality) 


operator for the moment. The following are all conditions: 


X=Y 
A = 23 
B = 2*3 


Conditions are tested and the next action determined by the result of 
the test with the IF and THEN statements used together. 


IF - THEN 


An IF - THEN statement has the form: 

IF (condition) THEN (instruction) 
For example: IF А = B THEN PRINT “EQUAL” 

IF A=@ THEN LET A= 3 

The instruction can be any valid instruction. The statement 
means: 
IF (the condition is TRUE) THEN (perform as instruction). 
IF (the condition is FALSE) the computer ignores the 
instruction after THEN and goes to the next line of the 
program. 


49 


In our simple program we can use the IF — THEN statement to insert 
in the program a conditional test which will stop the loop, without 
using the direct commands which we used in the last Unit. To STOP 
the program in the same way as with a direct command we can insert 
another line: 
15 IF A«9 THEN STOP 

This tells the computer that IF A = 0 (if it is TRUE that A is equal to 0) 
THEN it should STOP. IF A is any other value (if it is FALSE that 
A = 0) it ignores the THEN STOP instruction and moves to line 20. 
Enter this line into the program. RUN the program. 

Enter different non-zero values for A to see that if A 1s not zero then 
the program continues as before. Enter .000000001 to see that only if 
A is exactly zero will the STOP instruction be executed. Input 2 for B, 
and notice that the result is given as 2. This is due to the fact that 
calculations are only performed to a certain degree of accuracy. 

Enter .0000001 for A, and input B as 2. The computer returns 
2.0000001 as the value of S- the number is within the limits of 
accuracy. 

Now enter 0 for A. The program will stop, just as when we entered 
STOP as a direct command. Notice, however, that the message at the 
bottom of the screen is different. We get the message 9/15 on the ZX81 
(a STOP statement, 15:2 on the Spectrum).* The message is different 
because STOP in a program means “f the CONT command is 
received, proceed with the next program line', since if it continued with 
the same line it would just STOP again! As a direct command, 
however, STOP means ‘if the CONT command is received, start with 
the same program line', so that the computer does not miss out a 
program line. 


Now we have some extra control over the program, but it is still not 
satisfactory. We used IF A - 0 because in this program it is not a value 
we are interested in seeing added to B (a value used in this way is 
known as a DUMMY or SENTINEL VALUE - a value just used as a 
signal to the computer which would not need to be entered in the 
course of normal inputs). This stops the program and we can continue 
it, but the program just goes back into the loop. We need a method of 
proceeding out of the loop to end the program, or continuing with more 
program lines. 

We can do this with a STRING CONDITION. The conditional 
operators can also be used to express relations between strings - either 
string variables or simple strings. 

We insert the following lines: 

30 PRINT “RUN PROGRAM AGAIN ?(YES/NO)" 

55 INPUT A$ 

56 IF АЗ - ““ҮЕ58” THEN, GOTO 7 
“Оп the Spectrum, the statement after the THEN іп an IF- THEN statement is 
treated as the second statement in the program line. This is why we get 15:2, meaning 


line 15, statement 2. This is the only instruction used in the main text of this book 
(before Unit W2) where the statement number will not be 1 in an error message. 


50 


When the program gets to line 50 it will print out the message, and 
then put the cursor at the bottom of the screen. Because it has been 
told that a string input is to come, the cursor has quotes either side: 
"[L]". There is no need to type quotes. Whatever characters are 
typed in will be stored as A$. The string is entered by pressing 
NEWLINE (ENTER) after keying in the characters. Line 56 tells the 
computer to check if the characters in A$ are the same as the characters 
of the string ‘‘YES’’. If they are it goes to line 7. If they are not the 
program will continue to line 60. Notice that any string other than 
“YES” will cause the program to continue to line 60. 


Exercises 


1 Delete line 15 in our program, which we no longer need. 
Insert the new lines 50, 55 and 56. 

3 RUN the program. Enter “YES” in response to the string input 
cursor and see that the program loops back to line 7. 

4 Next enter “МО” to see that the program goes to line 60 and 
gives the message 0/60 (0 OK, 60:1 on the Spectrum). Run the 
program again. This time enter anything other than ‘ҮЕ’ or 
“МО”, to see that the program goes by default to line 60 if 
anything other than ''YES"' is entered. 

5 Experiment with the string input. What happens if you press 
NEWLINE (ENTER) without inputting anything? What 
happens if you try to key in quotes around the string? 

6 LLIST the program on the printer. The development of our 
program is complete, and we have run it to see that it works. It 
remains to renumber the lines, and this is easier to do if we have 
a listing. 


E6: Final Edit and Saving 


Our program ‘‘ADDER”’ is complete and works. We need, however, 
to renumber the lines. The procedure for this is as follows: 

1) Using the listing from the printer, renumber the statement lines 
in tens at the side of the old number. You can also count the 
number of lines in the program on the screen display, and 
multiply by ten to get the new highest line number. For our 
program, this will be 120. 

2) a) List the program on the screen. 

b) Usethe ^4 and | cursor control keys to bring the current 
line cursor to line 60 (the bottom line of the program). 

c) Press EDIT and pull line 60 down to the bottom of the 
screen. 

d) The new HIGHEST line number is 120. 

e) Change 60 to 120. 


31 


g) 


h) 


J) 


Press NEWLINE (ENTER). Line 60 remains, but it 1s 
duplicated by the new line 120. 
Delete the old line 60 by entering 60 and pressing 
NEWLINE (ENTER). 
Change each line number in this way, going from highest to 
lowest. 
Lines that contain other line numbers must have these 
changed to their new numbers. In our program we must 
remember to change line 56 to: 

90 IF A$=‘‘YES’’ THEN GOTO 30 
where 3@ is the new line number corresponding to the old 
line 7. 
Rename the program ‘‘ADDER2’’, at the same time as you 
change the line number of line 5 to 10. This program is 
different from the original version, and must be given a 
different name both for our reference, and the SAVE and 
LOAD operations. 
Run the program to check that it still works, and that we 
have all the lines, with any GOTO (line number) 
statements correctly renumbered. 
LIST and LLIST the program. 
SAVE “АОПЕК2”. 
Write the name of the program on the tape cassette, along 
with the tape counter readings. 
Put details of the program in your directory. 
Stick the listing of the program in the notebook you are 
using for documentation. 


52 


SECTION F: A GAME INTERLUDE 


F1: The Program Library 


In addition to the many programs and subroutines in the main body of 
the text, there are additional applications and games programs in the 
Program Library (Appendix VI). Our main objective is to enable you 
to write your own programs, and the programs in the text have been 
used to illustrate the use of techniques. Some are functional (do 
something significant) and some are just illustrative. You don’t have to 
key all the programs in the text into the computer, but you must 
understand them. However, you should key in all the shorter programs 
since it’s important to see how different types of program operate in 
practice. Analysing the longer programs is vital, even if you don't key 
them in. The use of flowcharts (to come in Lesson G) is helpful for this. 
There are also suggestions for programs you should write, to get 
practice in writing programs to perform tasks, after units dealing with 
specific techniques. 

The programs in the library are examples of applications and games 
programs, plus a number of subroutines for some of the manipulations 
commonly required in programs. You can key these in at any time if 
you want to see how the program works, find the program useful, or 
want to play the game. Once keyed in you can SAVE them on cassette 
and LOAD them back in quickly. None of the programs are very long, 
since it is difficult to analyse long programs, and this is what we want 
you to do. Keying in a program from a listing doesn’t teach you 
anything about programming, nor does running it. Writing or 
modifying a program does! We hope you find the programs 
entertaining or useful, but please treat them as a source of ideas and 
illustrations about programming, not as a fixed set of optimum 
solutions. Programs can always be improved! 

Be careful when keying in programs, especially if you don't 
understand how they work. (It might be better to work this out 
first - because, to labour the point, that way you'll learn something.) 
The S-cursor will mark some errors in lines for you and stop you 
entering them, but there are always other problems you can introduce. 
Check through your listing for errors and missing lines (surprisingly 
easy to do, even with numbered lines) before you run the program. 

You must also be careful to check that any necessary alterations have 
been made to the program if you are going to run it on a Spectrum, as 
noted in Unit W2. These are mostly minor but can be crucial. 


F2: A Game to Key In 


You have now spent a lot of time working through the essentials of your 
computer system and its BASIC, and you probably have the feeling 


53 


that thus far you haven't seen anything to persuade you that computers 
are particularly exciting machines. Far from being impressed by their 
capabilities, you may well be thinking, ‘What’s so good about a 
computer if you need to do all this to get it to do something that I could 
do in my head when I was six?’ Well, the following program may not 
be earth-shattering, but it does in fact reveal a fairly complex set of 
computer operations, as well as providing amusement. The program is 
called **BUG"' and it enables you to play a game that consists of 
dropping bricks from a height to squash the 'spider' (an asterisk) 
scurrying along below. If you have a militaristic or SF streak in your 
nature, or are an arachnid lover, feel free to change the name to 
“BOMBER” or whatever (in line 5). Whether you will enjoy it more 
by pretending you're napalming Venusians is your affair. It won't 
alter how the program works! 

To play the game, however, you first have to key it in. You won't 
understand at this point how it works (and won't for a few chapters 
yet), so you have to rely on keying it in exactly as listed. Like all the 
programs in the text, this one will look somewhat different on the 
screen or in a printer listing, since for clarity we have not reproduced 
the printer listings exactly, since printouts tend to contain broken 
words (when one line on the screen is full and the computer runs on to 
the next) and other possible confusions. Check each line carefully 
before you press NEWLINE (ENTER), and pay special attention to 
the punctuation. Notice that there are 2 spaces before the asterisk 
(spider) in line 50, and 3 spaces either side of the <=> (brick 
dropper/intergalactic space hod) in line 60. If you have any difficulty 
finding the right modes and keys for the characters you need, refer to 
the list in Section B (ZX81) and Unit W1 (Spectrum). It is very easy to 
end up typing a keyword instead of inputting it directly when you are 
keying in a listing (typing T,O instead of inputting TO, for example). 
If you do this it is not clear why you get the cursor indicating an 
error, since the line /ooks the same as the listing, so be warned. 


ZX81 Users! Notes 


The graphic character in line 160 is an inverse asterisk, (SHIFT B in 
Graphics mode) and in line 190 the characters are the SHIFTed 
graphic on the T key, the asterisk again, and the НІЕТеа graphic on 
the Y key. The comments in square brackets are intended to be helpful, 
not to be entered! 


Spectrum Users’ Notes 
Line 60 has an inverse video asterisk. Го get this, key CAPS SHIFT 


and the 4 key to get INV. VIDEO. Then input the asterisk. Use CAPS 
SHIFT and the 3 key to get TRUE VIDEO, i.e. normal black on 


54 


white, back. If you don't return to normal video, the quotes will be in 
Inverse, and so will everything after it. 

Line 190 has the unshifted G mode graphic on the 6 key, and then 
the CAPS SHIFT graphics on the 8 key and the 6 key as the graphics 
string. 


5 КЕМ "BUG" 

10 LET 5-0 

20 LET B=10 

30 FOR N-1 TO 12 


40 LET C23 L 
SQ PRINT AT 2O»C-2;" +" [2 Spaces #] 
60 PRINT AT (ЗЕ-2;" <=> и [3 5р, =>, 35 Sp] 
70 IF INKEYS ="6" THEN GoTo 

150 


80 LET B=B+(3 AND INKEY$ -"&" 
AND B<28)-(3 AND ІМКЕҮФ = 
"=" AND B»3) 
90 LET C=C+ INT ( ЕМО *2+1) 
100 IF C<30 THEN GOTO 50 
110 CLS 
120 NEXT N 
ie ERE np 1g RER "9! — DSCUREDIEM % SRATI 
140 STOF 


150 FOR F=4 TO 20 ЕТЕР 4 
160 FRINT AT Е,Б+1;"Ш" AT [Inverse %1 
FsB*1;" " 
170 NEXT F 
180 IF E+1 <> C THEN GOTO 50 Г <> іс one character] 
190 PRINT AT 20»C-1; "EF"; AT 
2130-2; "SPLAT" 
200 CLS 
210 LET S=54+1 
220 GOTO 120 


When you've got it all keyed in, LIST it to check it through again. 
Check the first screenful, then (on a ZX81) LIST 170 to get the rest of 
the program (with a line that was on the first screenful to keep your 
place). LLIST it on the printer. 

Key RUN then NEWLINE (ENTER) to play. The keys 5 and 8 
move you left and right respectively across the top of the screen. ‘They 
are chosen for the direction of the arrows printed on them. Key 6 will 
drop the brick. If you hit the spider it goes splat and you score a point. 
You have to hold the keys down to ensure that the computer will read 
the keys and perform the right operations. This is because it reads the 
keys only once in each pass through the loop (lines 50 to 100), апа 
might miss the input otherwise. 

When you’ ve played the game a few times, SAVE it on to tape and 
catalogue it. 


55 





| 


 ——————— ph 


wrt 


- ot 740 | 7% 03: 
2. -— ` 1484 4973 
^c, з 
I E 
á ja % 
“4: 5 
i э pis * Ж | c 
° m L 
474 f ° I 
TL à 
é ” ' / 
F | L 1% 
и. 
i í 
í А б =, 
i ` Wf i r ; 4 ъ 


PART TWO 


ESSENTIALS OF 
BASIC PROGRAMMING 











SECTION G: PROGRAMMING METHODS I 


G1: Programming 


Now that you can operate your computer and have written a short 
program we must look in greater detail at the activity we call 


PROGRAMMING and study how: 


COMPUTERS SOLVE PROBLEMS 


To enable them to do this we engage in the two main activities of 
programming: 


1 PRODUCE THE METHOD FOR SOLVING THE 
PROBLEM 
2 PRODUCE A WORKING PROGRAM 


The method for solving our problem is called an ALGORITHM. An 
algorithm 1s like a cookbook recipe, and is written down in steps in a 
brief English style we call PSEUDOCODE, and the method by which 
we arrive at the recipe is called STRUCTURED PROGRAMMING. 

We break the problem up into smaller sub-problems or sub-tasks in 
a step by step, modular fashion, starting from the simple initial 
statement of the problem and working down to lower levels of greater 
complexity (i.e. in a TOP DOWN manner). As we refine our problem 
our steps become more like the operations the computer can perform. 
Our final description of the lower level of the algorithm will be in terms 
of the control and other structures of the language. 

To help us produce the algorithm we use STRUCTURE 
DIAGRAMS. The simplest of these is a TREE diagram. The 
pseudocode description of the algorithm is easily written down from the 
descriptions of tasks in the tree diagram. We cannot 
key the pseudocode description of the algorithm into the ZX81 or 
Spectrum because it will not understand it, and there is no means of 
doing it anyway. We have to translate each section of the pseudocode 
into its equivalent in the BASIC language, which the computer 
understands, to produce a PROGRAM. 

For the computer to be able to run the program successfully and 
produce the results we require, there has to be a LOGICAL FLOW to 
the program. This is often difficult to see from the structure diagram, 
and so we use another diagrammatic technique to illustrate the flow of 
control through the program, i.e. determine the order in which the 
program modules or sub-programs are processed and the order of 
coding the specific instuctions within a module. 

This technique uses FLOWCHARTS. These are important for 
documentation purposes and are in common use. We will describe 
them shortly. 


59 


Producing a working program involves running and DEBUGGING 
(correcting errors in) our first effort. We then have to TEST the 
program with sample data and finally DOCUMENT it. In this first 
section on methodology we shall consider problem solving and coding 
the algorithm in BASIC in more detail. 

You will see that the first half of the activity we call programming is 
LANGUAGE INDEPENDENT. Having produced our problem 
solving method - the algorithm — we can code it into any computer 
language we wish. We need to know the language thoroughly and how 
the fundamental programming structures we have used in the 
algorithm - decisions, loops, subroutines, subprograms, 
functions — can be implemented in that version of the language which 
runs on the computer we are going to use. 

In this book we are using the ZX81 or Spectrum computers. The 
versions of BASIC are slightly different. All that this means is that 
whilst the algorithms to be coded for both machines will be the same, 
the final programs may be slightly different. 

Our algorithms and their representation in pseudocode and 
flowchart form are thus PORTABLE from one machine and language 
to another. 

Good coding habits are also important. There are good and bad 
ways of turning the solution to a problem into a working program. 
Style, presentation, ease of understanding, modularity, efficiency are 
all important. Throughout our book the emphasis will be on correct 
problem solving techniques and good programming practice, while you 
gain a thorough knowledge of BASIC. 

Here is our first rule of programming: 


PROGRAM CORRECTLY FROM THE START 


Remember - bad habits die hard! 


The material in this Section may initially appear dense and difficult 
to follow. Work through the text carefully, and refer back to this 
Section as often as you feel necessary, when each of the topics covered 
in the following Sections (dealing with the essential groundwork of the 
BASIC language) has been introduced. The exercises given in the text 
should be used to put into practice both the specific techniques involved 
and the general approach to programming presented here. 


G2: Problem Analysis 


Producing the algorithm, or method of solving the problem, is often the 
most difficult part of programming because it involves the most work. 
From the start careful planning and organisation are absolutely 
essential. The task is simplified when a structured design method is 
used, coupled with a diagrammatic representation of the algorithm 


60 


using a structure diagram or flowchart. The actual coding of the 
program in BASIC using the available language instructions is then a 
straightforward matter. 


To produce the Algorithm we must: 


STATE THE PROBLEM 

RESEARCH THE PROBLEM 

DESIGN THE ALGORITHM 

DESCRIBE THE ALGORITHM IN PSEUDOCODE 
AND FLOWCHART FORM 


= һі = = 
A GO м м 


Let us now consider each of these steps. 
1.1 State the problem fully 


1.1.1 STATE THE PROBLEM 
1.1.2 UNDERSTAND WHAT IS TO BE DONE 


To solve any problem we must know what the problem is and what is to 
Бе done. We later work out how to do it. A complete statement of the 
problem should include: 


(i) What information or data is to be input. 
(i) What answers or results are to be output. 
(uni) What operations аге to be performed on the data. 


At this stage a precise description of (111) may not be available. 


EXAMPLES 


Problem: Write a program which will print out the sum and 
average of five numbers input at the keyboard. 

Problem: Using the computer produce a telephone directory to 
contain up to fifty entries, which may be updated and 
assessed in an enquiry mode. 


In the first problem the input data, output data and operations are easy 
to see. The second is much more complex and needs more researching 
and information. 

What we are trying to do in 1.1.1 and 1.1.2 is to initially specify the 
problem as exactly as possible. When we analyse the problem further 
we may have to go back and ask for more information 1.e. a more 
detailed specification. 


61 


1.2 Research the problem 


1.2.1 RESEARCH AND ANALYSE THE PROBLEM TO 
SEE HOW THE COMPUTER CAN HANDLE IT 

1.2.2 IDENTIFY ALL FORMULAE AND RELATIONS 
INVOLVED 

1.2.5 IDENTIFY ALL DATA INVOLVED 


Here we start to determine how the computer may solve the problem. 
We need to find out and write down: 


(1) What formulae and expressions are to be used. 
(п) What kinds of data are involved - numeric, string, etc. 
(ui) What functions are involved. 
(iv) What is input and output data. 
(v) What is the form of this data. 
(vi) How much data there is. 
(vii) What processing is to be done and how many times. 


It is useful at this stage to start to create a data table (a table of variables, 
constants and counters), to record how we are going to store the data. 
Other questions we will ask when we are a little more experienced are: 

Have I solved a problem like this before? 

Can I use my solution or modify it? 

Has anyone else solved it? 

Where can I find their algorithm or program? 


ALL THE FACTS OBTAINED FROM RESEARCHING 
THE PROBLEM SHOULD BE JOTTED DOWN 


We can now begin to design the algorithm in a structured manner. 
1.3 Design the algorithm using structured methods 


1.3.1 BREAK THE PROBLEM DOWN INTO 
SUB-PROBLEMS 

1.3.2 USE A STRUCTURE OR TREE DIAGRAM TO 
HELP 

1.3.3 CLASSIFY MODULES OR PART MODULES AS 

— INPUT 

— PROCESSING 

– OUTPUT 

USE FUNDAMENTAL CONTROL STRUCTURES 

SET UP A DATA TABLE 

REFINE THE ALGORITHM UNTIL CODING 

INTO BASIC IS AN OBVIOUS EXERCISE 


кі = = 
92 G3 Go 
HD Qv > 


Structured programming means designing the algorithm in a top 


62 


down, modular fashion, with step by step refinement of the solution 
starting from the single statement of the problem which we place at the 
highest level. We break the problem into sub-problems at successive 
lower levels. Each sub-problem or module is one that can be solved 
individually. Structure diagrams or tree diagrams are useful as a 
representation of this refinement process. 


G3: Structure diagrams 


These enable us to break down the problem into distinct tasks and sub- 
tasks which eventually become simple enough to be coded directly in 
BASIC instructions. One form of these diagrams is TREE 
DIAGRAMS. The tree diagram has its trunk at the top of the page. 
We call this BOX 1 and give it the title: TASK TO BE DONE. We 
could have called it ‘problem to be solved’. 

For example, make a cup of tea or find the average of five numbers. 

We next break down the task into things to do. These are sub-tasks 
and each has its own box. For example: 


BOX 1.1: First thing to do 
BOX 1.2: Second thing to do 


Each sub-task is broken down into further sub-tasks: 1.1.1, 1.1.2 etc, 
each with their own boxes, the things to do placed in them becoming 
progressively more exact and simple. 

Breaking down a task into a tree diagram: 





first 
level 
second 
level 

її 1.2 145 

FIRST THING SECOND THING LAST THING 

pO TO DO 

third 
level 
ERE И Е. 1.2.1 1.2.2 3.253 4,2,2 L. 39 
Sub- Sub- Sub- Sub- Sub- Sub- Sub- 
task task task task task task | task 


The sort of programs you will start to write in BASIC are sequential, 
that is to say things are done one after another, so you need to be able 
to indicate that the program should first do one thing, then a second, 
then a third . . . and so on. You do this by drawing the boxes which 


63 


contain the tasks to be done in a straight line across the page next to 
each other for example: 


The numbers contained within each box identify where the box is 
placed on the tree. Take for example: 

The first digit shows it comes from the first level 1 ‘What is to be 
done’. 

The second digit ‘2’ shows it has come from the second level box 1.2 
‘Second thing to be done’. 

The third digit ‘3’ shows this box is the third sub-task in the 
sequence derived from which in turn is derived from . Into 
the boxes go brief statements of the actions needing to be performed. 
These are general statements at the top of the tree, e.g. ‘Get Sum of 
numbers’, but become more specific at each lower level, so that ‘Get 
Sum’ is broken down in the operations needed to produce the result 
‘Get Sum’, e.g. ‘Input first number’, ‘Input second number’, ‘Add 
the two numbers’. Finally the instructions become detailed enough to 
form our English language ‘pseudocode’ which can be written out, 
ready to be translated into BASIC instructions. 


AN EXAMPLE OF TREE DIAGRAM DESIGN 
Here is an example to try out. Suppose we have a robot with arms, legs 


and eyes which we want to program to make a pot of tea. Our major 
task for the robot is: 


1 
Make а Pot 


of Tea 





This can be broken down into sub-tasks which we put in order across 
the page: 











1 
МаКе а Ров 
of Tea 





Les 
Put Water 
in Pot 


Each of these sub-tasks is still far too complicated for our robot to do. 
We must break the problem down further. Breaking down 1.1 into sub- 
tasks we get: 


те Ме 1.1.2 11.3 
Fill the Kettle Plug in Kettle Wait Until 
with Water and Turn On Water Boiling 





The robot also needs to be told how to fill the kettle so we break this 
down as: 









1.2.1 
Fill the Kettle 
with Water 




















у 9000. Т МИК: 
Wait Until 
Full 


L. L La L 
Put the Kettle 
Under Tap 


On the next page is a complete tree diagram. Certain things are still 
wrong with this algorithm for our robot, but it does show you how a 
problem can be broken down. 


G4: Classifying Program Modules 
Most computer programs involve: 


INPUT 
PROCESSING 
and OUTPUT 


activities. 
As we are designing our programs and forming modules, it becomes 
evident from our pseudocode description of the algorithm which of the 


above functions the modules should have. Depending on the problem 
and the result of our algorithm design, modules may be separately 


65 


99 


T La 
Boil Water Put Tea 
the Pot 


Loan әш, 
Wait Get Tea 
Until Pot 
Water 


Boiling 








i E: 
Put Water 
into the Pot 


Lk ЖЕ! 
Take 
the Pot 
to the 
Kettle 





designated input, processing, and output functions or may have these 
functions nested as sub-modules. 


Module 2 
PROCESSING 


Module 





OR 






Module І 





Module 2 





PROGRAM 


G5: Control Structures 


PROCESSING OUTPUT 





Control structures are the statements or groups of statements 
(modules) in a program and algorithm by which the order of processing 
is controlled. Using them properly is the most important part of 
programming. 

BASIC is a line numbered language. The order of processing in a 
program is from the lowest line number in the program sequentially 
through to the highest, unless this is changed by using a control 
structure. Control structures link the different modules in a program 
together and are themselves modules. They will be dealt with in depth 
in the remainder of this section. 

To make our algorithm language-independent we can write them 
using a standard notation in pseudocode for the particular control 
structure together with its flowchart description. When we code the 
structures into the BASIC language the instructions used and the order 
of statements in the structure may be slightly different according to the 
version of BASIC and how ‘structured’ it is (i.e. how easily it 
accommodates these control structures). The structures we will study 


in BASIC are: 


(i) DECISION STRUCTURES 
(ii) TRANSFER STRUCTURES 
(iii) LOOPS 
(iv) SUBROUTINES 

(v) NESTED STRUCTURES 
(vi) SUB-PROGRAMS 


67 


DECISION STRUCTURES 


Computers make decisions by comparing the value of one variable 
against another. For example: 


IF А-0 THEN (do something) 
IF AS = “YES” THEN (do something) 


To make decisions they use relational (or conditional) and logical 
operators, like the equals operator above. 
Sinclair BASIC uses three decision structures: 
Simple decision 
Double decision 
Multiple decision 


As a result of these decisions control may be transferred to another 
program module, or local processing within the structure may take 
place. 


TRANSFER STRUCTURES 


These structures involve: 


(i) UNCONDITIONAL TRANSFER 


which is a direct transfer of control using a GOTO (line number) 
statement. Transfer is to another program statement or a module 
consisting of a group of statements. GOTO is a very powerful structure 
and must be used with care. 


(п) CONDITIONAL TRANSFER 


in which transfer of control to another segment is made as the result of 
a decision: i.e. IF (condition is true) THEN GOTO (line number). 
These program structures are discussed further in Section H. 


LOOPS 


The need for the repetition of simple tasks is one of the fundamental 
reasons computers exist. Loop structures are incorporated in most 
computer programs. A loop is a sequence of repeated steps in a 
program. This repetition must be controlled. We shall see in Section L 
that repetition is controlled by: 


(i) COUNTING 
(ii) TESTING FOR A CONDITION 


68 


There are three common loop structures: 


(i) Repeat (the process) forever! 
(ii) Repeat (the process) until (a condition is met). 
(ui) While (a condition holds) repeat (the process). 


Structure (i) is of little use, except that we have to note it and make sure 
it does not occur. 

In structure (11) the condition is tested after processing. 

In structure (iii) the condition is tested before processing. 

Sinclair BASIC uses a convenient and powerful set of statements for 
controlling repetition by counting called: 


FOR - NEXT Statements 
SUBROUTINES 


Structured programming involves breaking down а complicated 
problem into subproblems which can be worked on separately. 

SUBROUTINES are such separate independent program modules. 
They are distinct from SUBPROGRAMS which have similar 
properties in that they are routines or groups of program statements 
that are repeated more then once during a program run. 

Subroutine modules have a unique address and can have a name 
(like a person who lives in a house). Transfer of control to the 
subroutine from the MAIN PROGRAM, when the program runs is by 
reference to the subroutine address through a special SUBROUTINE 
CALL INSTRUCTION. This is the GOSUB (address of subroutine) 
statement. 

A return of control to the main program to carry on processing from 
where it left off is through a special instruction: RETURN. 

Subroutine structures in Sinclair BASIC are explained in Section N. 


NESTED STRUCTURES 


These are program modules or structures that lie entirely embedded 
within each other (like a set of Russian dolls). 
A simple nested structure 1s 
MODULE 1 
MODULE 2 
MODULE 3 


69 


In terms of program statements this would look like: 


module 1 
Inn 222 s, 
20 
module 2 
40 
. — 
BE ыз шч 
module 3 
SEL CIIM 2 
80 
IUD 
Ш. 
120. — ——— 
ГІП... 
140. 1. 


The flow of control is: 
START MODULE 1 


TRANSFER CONTROL  ——— 9» START MODULE 2 
TO MODULE 2 


TRANSFER CONTROL —————» START MODULE 3 
TO MODULE 3 


ү? COMPLETE MODULE 3 
TRANSFER CONTROL 


BACK TO MODULE 2 


COMPLETE MODULE 2 
TRANSFER CONTROL BACK 


Subroutines, subprograms, loops and decisions may be nested in 
programs. Nesting is dealt with more fully in Sections H, L and N. 


G6: The Data Table 


When designing a program it is important that our knowledge of the 
data and information pertaining to the problem is complete. All data 
will need to be assigned a VARIABLE name, unless it is a numeric 
constant used in a formula. 


70 


The variable type will be either: 


NUMERIC - numbers - A, N1, COUNT, A(I,J) 
STRING  -characters - A$, AS(I,]J) 
LOGICAL - numbers or characters - A, A$, NOT B 


Numeric variables will be integers, fractions, real and imaginary 
numbers. 

Strings will be names, characters and symbols. 

Logical variables will be the values TRUE or FALSE, 1 or 0 as 
appropriate to their use. Logic is dealt with in Section R. 

We also require to know whether our data is: 


INPUT 
OUTPUT 
or INTERMEDIATE 


Intermediate data is used in the body of the program, e.g. the value of 
a loop counter, or the intermediate result of a calculation. Intermediate 
data is useful for testing and debugging purposes when running the 
program or algorithm, using machine or hand traces. 

The equations, functions and expressions that will use the variables 
will need to be known. When dealing with equations, functions and 
expressions the units of the variables or parameters concerned must be 
known and should be stated. 

The first and simplest data table to construct is a descriptive list of 
variables to be used in the program. This is important for 
documentation purposes. For example: 


VARIABLE DESCRIPTION ITPR 


A First number Input 

B Second number Input 

SUM Sum of A and B Output 

A$ User response to Input 
‘RUN AGAIN?’ 


For program design purposes the value ascribed to each variable at 
different points through the programs can be added. This forms a data 
table that is useful for checking the algorithm before and after coding it 
into BASIC, and is also a way of analysing errors in your own 
program, and understanding how other programs work. 


71 


ALGORITHM VARIABLES 


MODULE N 
N. 1 





Loop counters are included in the list of variables. If their values are 
used for calculation inside the loop, this should be stated. There are 
some examples of this type of data table in the text. 


REFINING THE ALGORITHM 


The tree diagram should be further broken down and refined until the 
final sub-modules correspond to recognisable BASIC statements and 
structures. As you get more experienced, you will recognise more 
complex structures, and the solution to a problem wil become 
apparent at an earlier stage. 


G7: Describe the Algorithm 


1.4.1 WRITE OUT YOUR METHOD OF SOLVING 
THE PROBLEM (THE ALGORITHM) IN STEPS 
ІМ А SIMPLE ENGLISH STYLE 
(PSEUDOCODE). 

1.4.2 DRAW A FLOWCHART SHOWING HOW THE 
PROGRAM WILL RUN FROM START TO 
FINISH. 

1.4.3 TEST THAT THE ALGORITHM WILL WORK 
BEFORE CODING IT INTO BASIC. 


Having broken our problem down into distinct things to do, or 
subproblems, to a stage where we are able to write a BASIC program, 
we need to do at least two things before we code. These enable us to 
write programs that work and that other users can understand. 

The algorithm description in pseudocode or flowchart form is an 
important point of the documentation of your programs. This is not 
written as part of the program but as a separate document which will 
also include a listing of the program. This is important for other 
programmers who may want to modify your program or use it as part 
of a larger program, and for you yourself if you come back to it after a 


72 


period of time and cannot remember how you designed it! The 
program listing alone is often not enough, if the algorithm is complex, 
to show how the program works. 


G8: The Pseudocode Description 


In the structure or tree diagram - which we draw out in rough on a 
piece of paper as we design our solution — each block or module right 
down to the lowest level has an English description of the task to be 
done inside it. (The very lowest level tasks will be described in 
sentences that are very similar to the BASIC program statements 
themselves, as you will see in Programming Methods II.) 

Our algorithm will be written out, in a step-by-step fashion, and will 
include all the descriptions in the boxes. The highest or first level 
description (simple box) will be the algorithm and program title. The 
second level will be the titles of the program sections. Each of these 
major sections will encompass a further group of modules, all of which 
will be named in our description of the solution. 

The lowest level of our tree diagram will be the specific instuctions 
the computer has to perform. These will be translated into the BASIC 
language on an almost one to one basis, and will contain the important 
and easily recognised language structures, for making decisions, 
branching and jumping, and repetition that we have previously 
mentioned. (A summary of pseudocode descriptions of some control 
structures and their flowcharts with BASIC program equivalents is 
given in Section 0, Programming Methods II.) If you imagine turning 
the tree diagram on its side and taking away the boxes, the descriptions 
that are left constitute a pseudocode description of the algorithm. 

As an example, let’s look at the tree diagram and the algorithm 
description for the problem of asking our robot to make a pot of tea. 

Using our tree diagram we can write down our algorithm for making 
a pot of tea as a sequence of instructions (to be coded later into a 
computer language). We use the English language as our pseudocode 
and our program is written directly from the sub-tasks in the bottom 
line of boxes in the tree diagram. 

We use the boxes at higher levels in the tree to define distinct 
modules. Comments or REMARK statements identify each module 
and explain what is being done in each algorithm section: 

Remark * * Algorithm for robot to make pot of tea * * 
Remark * Boil water - task 1.1* 


1,4,4 ЕШ the Кеше with water 
1,1-4 Walt until the water is boiling 
1.3 Plug in the kettle and turn it on 


Remark * End of task 1.1* 

Remark* Module - Put tea in the pot — task 1.2 * 
Ix Get toe pot 
1.2.2 Put 200 tea bags in the pot 


73 


Remark” Епа of task 1,2% 
Remark * Module - Put water in the pot - task 1.3 * 
1,2,1 Take pot to kettle 
1,2,2 Stir tea with spoon 
1.54 Put lid on tea pot 
Remark * End of task 1.3 * 
Remark * * End of Algorithm - tea is made * * 
You can see that the tree diagram shows why each part of your 
algorithm is included and why it is in the particular position in which 
you have placed it on the tree. 
The tree diagram contains information about three things: 


(1) The problem broken down into different levels of detail starting 
from the general concept of what is to be done down to the 
specific activities and instructions which will enable the problem 
to be coded. 

(2) ‘The order in which instructions must be performed. 

(3) The comments which must be included to explain what the 
program is doing. 


Exercises 


1 Our algorithm has the following mistakes in it: 
a) Some instructions are wrong. They are spelt incorrectly 
and the robot will not be able to recognise them. 
b) Some instructions are in the wrong order. 
c) Some instructions are missing in the algorithm. 
d) Some instructions are missing on the tree diagram. 
Find the mistakes! 
2 Correct the tree diagram and the algorithm. 
3 Expand the tree diagram and the algorithm to a further sub-task 
level. For example: 
„л Fill the kettle 
becomes 
1.1.1.1 Put kettle under tap 
1.1.1.2 ‘Turn on tap 
etc. 
4 Draw а tree diagram and write the algorithm in pseudocode for 
a robot to set up and switch on your microcomputer system. 


G9: Flowcharts 


Flowcharts are a second graphical method used in designing programs. 
They consist of linked boxes of different shapes. Each shape has a 
different use and, as with tree diagrams, each contains a brief 
description of what the program should do at a particular point. 

It is harder to design programs using flowcharts than with tree 


74 


diagrams. Their power comes from using them to help make visible 
and describe the flow of control in the algorithm and the resulting 
program. They are used to help code the program into BASIC 
instructions, and later form an important part of the 
DOCUMENTATION оға program. Note that flowcharts express the 
important control structures used in programming in diagram form. 

We give a selection of standard flowchart symbols here. There are 
additional ones, but their usage varies. The conventions of use should 
be followed if you wish other people to understand your flowcharts. For 
your own use, in analysing programs, you may be less exact, but not 
less systematic. Flow in a program can be illustrated by a selection of 
blobs and rectangles only, given that the lines of flow are correctly 
given, and the right words are written in the blobs! Doing this is all 
right for yourself, but not if your flowcharts are to be comprehensible to 
others. 


FLOWCHART SYMBOLS 
Flow lines. These connect the program blocks. 


Y “pes The arrows show the direction of flow, and are 
very important. 


This symbol represents any kind of processing 


function, that is general Programming 
dinis Statements, i.e. ''Purchase Tea'' or 
LET A- В + С. 


This represents а decision, with а Conditional 


— test, e.g. “Is there another shop open” or 
<> IF A=3 THEN ... It has a Yes/No branch, 
No according to whether the condition is True or 


False, which determines the program flow. 


This represents either Output in the program 
m" to the screen or printer, or Input from the 

keyboard, e.g. PRINT “HAVE YOU A 

PACKET OF TEA?” or INPUT B. 


This represents a named process that is 
specified elsewhere, e.g. Subroutine GOSUB 
1000. The subroutine would have a separate 
flowchart. 





75 


This represents an exit to or entry from another 
part of the flowchart, allowing one part of the 
chart to be connected to another part. Used 
when another direct line link would be 
confusing, or to connect to a separate page. 


This represents the Crossing of two Flow 
Lines. They are not connected. 


This represents the Junction of Flow Lines. 


The two lines of flow join. 


STOP Terminal Point, e.g. Start, Stop, Pause. 


A flowchart does not branch out like a tree diagram. It always 
converges to the stop point. It has a direct relationship to the program 
it describes. Writing down a flowchart is rather like drawing a diagram 
of the program itself. Below are some examples of simple flow 
structures, with the program and the flowchart. 


FLOWCHART PROGRAM 


1. Simple sequences 


10 LET X = 5 
20 INPUT Y 
30 PRINT X,Y 





FLOWCHART PROGRAM 


2. Decision and program branch 


40 IF Y-0 THEN GOTO 70 
50 LET X=100 

60 GOTO 80 

70 LET Х-0 

80 PRINT X 

90 STOP 





Notice that we have omitted a flowchart symbol for line 60. This 
GOTO is indicated by the flow lines. The same is true of the GOTO in 


the conditional statement of line 40. 


10 INPUT X 

20 IF X-0 THEN GOTO 50 
30 PRINT X 

40 GOTO 10 

50 REM **END** 





PRINT X 





77 : 





Notice that the above flowcharts represent the programs line by line. 
Flowcharts can also be less detailed, and the flowchart symbols used to 
represent program blocks (sequences of program instructions) or 
modules rather than one or two lines. They then describe a less detailed 
flow structure. We might have a flow that was represented like this: 


INSTRUCTIONS 


INPUT 
10 
NUMBERS 


FIND SUM, 


AVERAGE 





This is like a flowchart of a higher (less specific) level of a tree diagram. 
Each section could have a more detailed flowchart drawn up to show 
the individual lines of the program, or comments could be added to the 
blocks above, relating the program lines to the blocks: 


78 


INPUT Input loop in lines 


10 а Г 
40 t 
NUMBERS o 69 





You will soon start to write short programs, and should draw up 
flowcharts with each program line or instruction indicated separately. 
Later, for longer programs with large numbers of lines, the flowcharts 
must be condensed where the sequence is simple to follow in the program, to 


keep them of manageable size. Any complex manipulations should still 
be included in full. 


EXAMPLES 


(1) Here is a flowchart for our robot. We are going to ask it to buy a 
packet of tea. 







ENTER 
SHOP 






HAVE 
YOU A PACKET 
OF TEA 


LS 
THERE ANOTHER 
SHOP 






PURCHASE 


TEA 


79 


In the same way as our ‘making a pot of tea’ problem which the robot 
has to solve, each of these boxes must be broken down into simpler 
instructions. On a simple flowchart it may not be possible to see how 
the problem has been broken down. What we must do is either draw 
the whole flowchart again with more detail or draw new expanded 
flowcharts at specific points, e.g. “ENTER SHOP” could be replaced 
with the following: 





80 


(2 Here is a flowchart of a program to input two numbers, output 
the sum, and ask you if you want to run the program again. 





81 


INPUT À 

INPUT B 

LETS = A+B 

PRINT S 

PRINT ‘‘RUN AGAIN? 
(ҮЕ5/МО)” 

INPUT A$ 

IF A$ = ‘‘YES’’ THEN 
GOTO 10 

STOP 


AN EXAMPLE OF STRUCTURED DESIGN 
Problem: Find the average of five numbers: 


(1) TREE DIAGRAM 


Find Average 
of 5 numbers 


Get each 
Set counter number, add Find Print 
& sum to Q it to the sum Average Average 





Let Sum = 
Let Counter 


Add 1 Input 
to counter number 


End of 
summing if 
counter = 5 





Let Let If Counter Let Print 
Counter = Sum = = 5 then Average Average 
Counter +łŁ Sum+X end summing =Sum/5 





(2) FLOWCHART 


START 






SET 
COUNTER 
-0 






92 








ADD 
COUNTER 









Note that the flowchart and program test whether the counter value is 
less than 5, using the < symbol. 


(3) PROGRAM 


REM “AVERAGE” 

REM ** PROGRAM FINDS AVERAGE OF FIVE 
NUMBERS INPUT ** 

REM ** START ** 

LET SUM = 0 

LET COUNTER = @ 

LET COUNTER = COUNTER + 1 

INPUT X 

LET SUM = SUM + X 

IF COUNTER < 5 THEN GOTO 60 


83 


100 LET AVERAGE = SUM/5 

110 PRINT AVERAGE 

120 KEM ** END ** 
The operand “” means ‘divided by’ and is equivalent to the ‘+’ 
symbol. 


Exercises 


1 Design an algorithm (using tree diagram) and write a BASIC 
program with a flowchart to find the sum and average of ten 
numbers to be input at the keyboard. 

2 Produce the tree diagram, flowchart and program which 
calculates the area of any rectangle. 

3 Design the algorithm, BASIC program and flowchart which 
calculates the total volume and weight of three boxes to be 
airfreighted from London to New York. Use the following data: 
BOX LENGTHCM BREADTHCM HEIGHTCM WEIGHT KG 


1 20 4 2 2 
2 40 3 6 2.5 
3 70 10 15 20 


Test that it works! 


G10: Testing the Algorithm 


It is always best to make sure your method of solving the problem 
actually works before coding it into BASIC. This pre-coding check is 
known in the programming trade as a DRY RUN or WALK 
THROUGH. 

Using the DATA TABLE, we check through, module by module, 
the values of all the variables, expressions and counters step by step 
through the algorithm. This will uncover errors in the logic and 
method and will save time when debugging the finished product later 
on. Professional programmers always do this as they have to work to 
very tight time schedules, and by doing things properly at the start they 
save time later on. We would like you to try a few walk throughs on the 
simple programs you will be designing at first, just to get the hang of 
the idea. 

We have now covered the first essential steps in designing a program 
and have seen a simple coding process. We have talked about methods 
and concepts and introduced some new terminology. After concepts we 
go to detail. 

The algorithm is ready to be coded into a BASIC program. In doing 
this we are going to put into the program the fundamental 
programming tools, which are language structure and control 
structures. We have to know what these structures or tools are before 
we can use them. This requires a look at how Sinclair BASIC, through 
small groups of instructions, enables decisions to be taken, branching 


94 


and jumping to different parts of the program to happen, repetition of 
parts of the program to take place and how separate modules called 
subroutines and sub-programs can be called into action where 
necessary — these are the language structures. 

Let’s go and meet them! 


85 


SECTION H: CONTROL 
H1: Control in Programs 


The statements which make up a BASIC program are numbered. 
BASIC is thus called a LINE NUMBERED LANGUAGE. Control in 
all BASIC programs is carried out by reference to these line or 
statement numbers. The ZX81 and Spectrum will normally run a 
program from the lowest numbered statement through to that with the 
highest number unless instructed to do otherwise. This is exactly what 
concerns us here, and thus we need to recognise that we can control the 
order in which program statements are executed by using four 
important instructions in Sinclair BASIC: 
- GOTO (for direct transfer) 
- IF-T HEN (for decisions and 
branching) 
- FOR-NEXT (for loops 
(repetitions)) 
- GOSUB-RETURN (for 
accessing program modules 
called subroutines) 
These instructions are used singly or combined together with other 
instructions to form groups of program statements called CONTROL 
STRUCTURES. There are four principal control structures: 
- DECISION AND BRANCH 
- LOOPS 
- SUBROUTINES 
- NESTED STRUCTURES 
In this Section we will discover how to take decisions and branch to 
other parts of the program. We will study the remaining structures 
later in Part Three. The most important property of a computer is that 
it can be programmed to make decisions, by using the relational or 
conditional operators of BASIC. 


H2: Condition Testing 
CONDITIONAL OPERATORS 
Conditional operators are also called relational operators as 


they determine the logical relationship between two 
expressions, numeric or string, as: 


Equality: = 
Inequality: «<> 
Greater than: > 
Less than: < 


Greater than or equal to: >= 
Less than or equal to: < 


The priority of conditional operators is 5. Priority will be 
explained in Section J. 

They are executed in order left to right across a statement 
unless in brackets. 


We often need to use the complements or opposites of these operators 
in decision making. The complements are: 


Operator Complement 

equality = inequality <> 

greater than > less than or equal to < = 
greater than or equal to > = less than < 


The reverse operations are true in each case. 


H3: IF-THEN 


IF-THEN 


Conditional operators are used with: 
IF-THEN statements 


IF (CONDITION IS TRUE) THEN (PERFORM AN 
INSTRUCTION). 
For example: 40 IF (А = B) THEN GOTO 10 

50 IF C <=6 THEN STOP 

60 IF J > K THEN PRINT “J” 


The format of the statement is: 
IF (CONDITION) THEN (INSTRUCTION) 


Any BASIC instructions can be used in this kind of statement, 
although a number are unlikely to be useful (e.g. NEW, CLEAR). 
In general if the condition in the program line is TRUE then the 
instruction following the condition is obeyed. If the condition is not 
TRUE (FALSE) then control passes to the next line. 

This powerful facility enables us to branch and transfer control to 
another line in the program. 






IS YES BRANCH 







THE CONDITION 
(TRUE PATH) 
TRUE? 






NO BRANCH (FALSE PATH) 
GO TO THE NEXT LINE 


87 


H4: GOTO [Instructions 


GOTO 


The normal control sequence in a program is via numbered 
statements — from the lowest to the highest. GOTO (line 
number) switches control to the line number specified: 


100 GOTO 20 

200 GOTO (B + C) 
As a command GOTO 30 executes a program from line 30. 
Unlike RUN, with this method variables are not cleared 
before execution. 


The Spectrum includes a space between GO and TO when printing 
this instruction. 


Exercises 


Key in and run this program which checks that only positive numbers 
are input and gives a bad data error message as well as prompting for 


the next input. Notice the use of IF-THEN and GOTO. INPUT both 


positive and negative numbers. 


10 REM*INPUT CHECK* 

20 INPUT A 

30 IF A»0 THEN PRINT A 

40 IF A«-0 THEN PRINT "BAD IN 
PUT" 

50 PRINT "HAVE YOU ANOTHER NUMB 
ER? ANSWER YES OR NO" 

60 INPUT AŠ 

70 IF А5 ="YES"THEN GOTO 20 

88 STOP 

90 REM*END INPUT CHECK* 


Now try these exercises which demonstrate the power of GOTO: 


1 10 PRINT “CENTURY”; 
20 GOTO 10 


Run this program 


2 10 GOTO 80 
20 PRINT “COMPUTERS'”'; 
30 GOTO 10 
40 PRINT ‘‘PERSONAL”’; 
50 GOTO 20 


88 


60 PRINT ''SINCLAIR''; 
70 GOTO 40 
80 GOTO 60 


Key it in and sort it out! 

This is called ‘spaghetti programming’. Structured programming 
techniques have been designed to avoid the excessive use of GOTO 
statements. 


3 10 INPUT A$ 
20 PRINT A$; 
30 GOTO 10 


INPUT some graphics characters 
and watch the patterns! 


4 Кеуіп and run this example: 


10 INPUT A 

20 IFA = 1 THEN FORI = 1 TO 10 
30 PRINT “CENTURY” 

40 IF A=1 THEN NEXT I 

50 STOP 


Line 10 asks you to input a number. 

Line 20 examines if it is equal to 1. IF this condition is TRUE then a 
FOR-NEXT loop is set up to print “CENTURY” ten times. If it is not 
TRUE then control passes to the next line. 

Line 30 “СЕМТГКҮ” is printed once. 

Line 40 the condition is tested again. If TRUE the loop continues 
and CENTURY is printed again. If not then control passes to line 50. 

Line 50 stops program execution. 

Can you understand it? If not wait until you have read the section on 


LOOPS. 

H5: Decision Structures 

DOUBLE DECISIONS 

The simplest decision involves the evaluation of a LOGICAL 
CONDITION - i.e. a condition that may have the value of either 
TRUE or FALSE. A result of this evaluation decides which part of a 


program is executed next. These parts of the program are called 
TRUE TASK and FALSE TASK. 


89 


The flowchart for the Double Decision STRUCTURE is: 





It is called a double decision as there are two alternative modules that 
can be performed. 

In the flowchart, if the indicated condition 1s true, then the program 
section representing the True task is carried out, otherwise the 
program section representing the False task is performed. Only one of 
the paths from the condition test is taken, and the program will 
continue at the statement represented by the arrow at the bottom of the 
flowchart. 

Each task can be a single instruction or a statement or a group of 
instructions. 

The Double Decision Structure is known by the general name of the 
"IF-THEN-ELSE Decision Structure’’. Its general form 1s: 

IF (condition) THEN (true) ELSE (false) 
This means: IF the condition tested is True THEN perform the True 
task, and IF the condition is not true perform the False task. 

Our algorithm description of it would look like: 

1. Decision Module. 

1.1 Do the test. If result is True then 
1.22 По True task 

1.3 Otherwise do False task 


We can write this formally in pseudocode as: 


90 


module - decision 
if condition 
then True Task 
else False Task 
end if 
end module 
End if and end module are bounds to the structure. In Sinclair BASIC 


we code it as: 


10 IF (cond) THEN (branch to True task) 
20 (False task) 
Note that in this case the only literal equivalent of BASIC from the 
pseudocode is with the use of IF and THEN. 
The branch to the true task is made with a GOTO instruction. For 
example: 
10 IF A»0 THEN GOTO 100 
20 REM * FALSE TASK * 
ЗӨ uus 


90 GOTO 120 
100 REM * TRUE TASK * 
110 PRINT A 


If we did not branch to the true task starting at 100 and used: 

10 IF A20 THEN PRINT A 

20 REM FALSE TASK 
in line 10, the true task would be processed and control would then 
pass to line 20 - the false task. In other words, both tasks would be 
processed! Watch out for this. 
EXAMPLE: Input two names as strings. The program compares 
them and prints them out in alphabetical order: 





91 


14 REM * ALPHA * 

20 INPUT A$ 

30 INPUT B$ 

40 IF A$<B$ THEN GOTO 80 


FALSE 50 PRINT B$ 
TASK 60 PRINT A$ 
70 GOTO 100 
TRUE 80 PRINT A$ 
TASK 90 PRINT B$ 
100 STOP 
110 REM * END ALPHA * 


THE SINGLE DECISION 


This is a special case of the double decision structure in which there is 
only one task to perform - the True task. 


TRUE 


TRUE 


TASK 


This is called an IF-THEN decision structure. Its BASIC form is: 
IF (Condition) THEN (True) 
Which means: 
IF (the condition test is true) THEN (perform the true task) 
Our algorithm description would be: 
1. Decision module 
1.1 Perform test 
1.2 If True, process true task 


92 


A brief formal pseudocode description is: 
mod - Decision 
if Condition 
Then P 
end if 


end mod 


Our BASIC statement is: 
IF (condition) THEN (TRUE) 


EXAMPLE: Input numbers and stop if a number greater than 10 is 


input: 


10 INPUT A 
20 IF A>10 THEN STOP 
30 GOTO 10 


5ТОР 


Note the abbreviation of True to Т апа False to F. 
MULTIPLE DECISIONS 


There is often the need in programs to perform several tasks based on 
the result of a set of conditions. To solve these problems we use a 


93 


multiple decision structure. This kind of structure is especially useful in 
breaking up larger tasks into smaller ones. 

Multiple decisions are most conveniently handled by multiple logical 
operations. This is covered in Section R. We will consider the 
conventional way of handling them. 

As an example of multiple decisions consider a food vending 
machine. You put a coin in and press the respective button of the 
article you wish to be delivered to you. Another example would be a set 
of arithmetic testing programs, with questions in each. The computer 
would ask you which set of tests you required, you would key in the 
reply and, from several alternatives, the required program would run. 


The flowchart for such a structure is: 


START 





Where C1, C2, C3 are the conditions and Р1, Р2, P3 are the True 
tasks. 


EXAMPLE: Input any of three letters A, B, C and print out a 
corresponding reply. 

= FRINT "ENTER AoE üR C" 

10 INFUT ñ$ 

20 IF АФ-"А" THEN GOTO 60 


94 


30 IF А%Ф-"Е" THEN GOTO ЕО 
40 IF AS="C" THEN GOTO 100 
20 STOP 

60 PRINT “YOU INFUT A" 

70 STOP 

S0 FRINT “YOU INPUT Е" 

90 STOP 

100 PRINT “YOU INPUT C" 

110 STOF 


The Pseudocode description of this structure is: 


case 
if Cl 
then P1 10 IF (C1) THEN (P1) 
if C2 
then P2 20 IF (C2) THEN (P2) 
if C3 
then P3 30 IF (C3) THEN (P3) 
endcase 
endmod 


PROGRAMMING WITH GOTO 


When programming in BASIC take great care in how you use the 
GOTO statement. It takes two main forms. Used on its own it 1s called 
an unconditional GOTO and when used with IF-T'HEN it is called a 
conditional GOTO. 

GOTO enables you to jump around in a program like a flea on a 
blanket - don't do it! Try and code your program to execute in 
sequence and avoid it becoming a bowl of spaghetti. Excessive use of 
GOTO makes programs difficult to refine and debug. Relationships 
between the program paths become difficult to follow. However — do 
not take the other extreme and write awkward complicated code to try 
and avoid GOTOSs! 

Ideally, unconditional GOTO statements should only be used to 
skip over code and not to repeat code sections (i.e. they should only be 
used to transfer control forward in a program). 

Do not put an unconditional GOTO inside a loop or subroutine to 
jump out of it. Do not jump inside a loop or subroutine, because you'll 
find that jumping in and out of loops can cause unpredictable results. 

Do not jump to another GOTO. For example: 

100 GOTO 200 
200 GOTO 300 


95 


or else 


100 GOTO 100 ! 


Exercises 


1 


2 


H6: L 


Write a program to input integer numbers and stop if zero is 
input. 

Write a program to input integers and count the number of 
times zero 15 input. 

Write a program to input integers and calculate the percentage 
of zeros input. 

Write a program which prints out the result of dividing any two 
numbers’ input and gives a “Һай data - try again” message if 
any of the input values is zero. 

Write a program which will print out on request a lunch menu 
for the different days of the week. 


ogical Operators: AND/OR 


We will only introduce you to simple logical operations here. Logic is 
dealt with fully in Section R. 


Use 


of the AND and OR statements enables us to combine 


conditional statements in powerful ways to make more complex 


decisio 


ns in programs. 


AND 


AND combines relations so that the expression: 


e.g. 


(condition 1) AND (condition 2) 
(A = B) AND (В>1) 


is TRUE when BOTH conditions are TRUE. 
It is FALSE when one or both conditions are FALSE. 


OR 


e.g. 


OR 


combines relations so that the expression: 
(condition 1) OR (condition 2) 
(A = B) OR (B<>1) 


is TRUE when EITHER condition is TRUE. 
It is FALSE when both conditions are FALSE. 


The expressions formed by the use of AND and OR are used with 


LE ua d. 


HEN statements. For example: 


20 IF Х>1 AND X«10 THEN PRINT 
'* BETWEEN 1 AND 10” 


96 


50 IFX<>2 AND X<>3 THEN PRINT 
< A МОТ EQUAL TO 2 ОҚ” 
40 IF A=B OR B=C THEN LET F=F+1 


The first example will be true if X is greater than 1 and X is also less 
than 10, and the message will be printed. If X was 11, the first 
condition would be true, but the second false. The whole expression 
would then be false. 

Notice the danger with the second example, in that we say in English 
‘not equal to 2 or 3’, but we must key in an expression using AND. It is 
clear once you realise that two conditions are to be tested — ‘not equal 
to 2 and not equal to 3’. If, for example, X were 3 when this line in the 
program was reached, then the second condition would be false in this 
expression, and the whole expression would also be false. 

The third example would be true if ezther A was equal to B or if B was 
equal to C. It is also true if both these conditions are true. 

We can also combine more than two conditions: 

20 IF A=BANDB=CANDC = 20 THEN STOP 
will stop if all three conditions are true. If one or more is false then the 
whole expression is false. 

Similarly: 

20IFB-20R B-3ORB-4THEN LET B- 1 
will make B - 1 if B is equal to 2 or 3 or 4. 

It is also possible to use combinations of AND and OR: 

30 IF (A = BAND B>2) ОК (A = 2 AND B = 3) THEN GOTO 60 
The expressions in brackets are evaluated first. The first expression in 
brackets will be true if B is greater than 2 and equal to A. The second 
expression will be true if A is 2 and B is 3. The program will pass 
control to line 60 if either expression in brackets is true. 

To summarise: where T1, T2 etc. are true conditional expressions 
and F1, F2 etc. are false conditional expressions: 


(T1) AND (T2) TRUE 
(T1) AND (F2) FALSE 
(F1) AND (T2) FALSE 
(F1) AND (F2) FALSE 
(T1) OR (T2) TRUE 
(F1) OR (T2) TRUE 
(T1) OR (F2) TRUE 
(F1) OR (F2) FALSE 


Each condition may also be another AND or OR expression. 


Exercises 
Work out what will be printed by these programs, then key in and run 


them to check. The operator ‘‘/’’ means ‘‘divided Бу” (+) and “%” 
means ''multiplied Бу” (*). 


97 


Make sure you have got the programs correct before you run 
them. Work out both sides of each expression using a relational 
Then, giving each expression a T or F value, work 
out the bracketed AND/OR expressions. This gives you a T or F 
value for the whole bracket. Then work out whether the whole 


operator first. 


LET A=2 

LET B=3 

LET С-10 

LET X=15 

IF X/B=A AND C/A=5 THEN PRINT 
"LINE 50 TRUE" 

IF X/B-A OR C/A=5 THEN PRINT 
"LINE 60 TRUE" 

IF X/B=C/2 AND X>=15 THEN PRINT 
"LINE 70 TRUE" 


LET A-20 

LET В-150 

LET X=7.5 

LET Y-2 

LET 5-В/20 

IF S=X AND X*A-B AND Y-2 THEN 
PRINT "LINE 60 TRUE" 

IF X-B OR X«20 OR X>2 THEN 
PRINT "LINE 70 TRUE" 

IF (X=7.5 OR Ү-10) AND (A/Y-1 
@ AND В-150) THEN PRINT "LINE 
80 TRUE" 


expression will be true or false. 


Write some similar programs for yourself to experiment with all 


the relational 


operators used with AND and OR. 


98 


SECTION I: PRINTING 
I1: PRINT LPRINT 
PRINT 
The PRINT statement is used to output information by 


displaying it on the screen. 


It can take many forms. For example: 


10 PRINT A prints out the value of 
numeric variable A 

20 PRINT B$ prints out string variable B$ 

30 PRINT “YOUR NAME?" prints out whatever is 


included within the quotes 
(inverted commas) 


40 PRINT (B**2 — 4*A*C) prints out the calculated 
value of the expression 
50 PRINT leaves a blank line 
LPRINT 


The LPRINT statement is used to output information by 
printing it out on the printer. 


The LPRINT statement is used in exactly the same way as the PRINT 
statement, but produces printer and not screen output. If the printer is 
not attached LPRINT statements are ignored. 


The screen size for printing is 22 PRINT lines down the 
screen, and each line is 32 columns (character spaces) wide. 
The actual screen size is 24 lines by 32 columns, but the 
bottom two lines are reserved for commands and operating 
messages. The lines are numbered @ to 21 down the screen 
and the columns 0 to 31 across. 


The PRINT statements shown above each commence at the left-hand 
side of the screen, and each PRINT statement moves the printing 
position to the start of the next line after it prints whatever it was told 
to. Lines of greater than 32 characters will go on to the next line 
automatically. 

To clear the screen of printing we use the CLS (Clear Screen) 
statement. 


99 


CLS 


CLS erases all printing on the screen, and sets the new print 
position at the start of the top line of the screen. 


I2: Spacing Items on the Screen 


Е 


А semicolon (;) between two items causes the printing of the 
second item immediately after the first. 


For example: 

10 PRINT A;B$ 

20 PRINT “АУЕКАСЕ”;С 
Try the following program: 

10 LET A=6.89 

20 LET B=87.6 

30 PRINT A;B 

40 PRINT ''AVERAGE"'';(A + B)/2 
The display is: 

6.8987.6 

АУЕКАСЕ47.245 
This does not give а very satisfactory display since values run into each 
other. One simple way to overcome this is shown below. 

10 LET A= 6.89 

20 LET B=87.6 

30 PRINT A;" "В 

40 PRINT “AVERAGE ”;(А+В)/2 
The display now becomes: 

6.89 87.6 

AVERAGE 47.245 


ci 


A comma (,) between two items causes the print position to be 
shifted on (at least one place) to either column 16 or to the 
next line column 0. 


For example: 
10 PRINT A,B 
20 PRINT A$,B$ 
30 PRINT “АУЕКАСЕ”,С 
Try the following program: 
10 LET A= 7.65 
20 LET B= 8.67 
30 PRINT “AVERAGE” (А + B)/2 


100 


40 PRINT 
50 PRINT ‘‘NUMBER!1’’,‘‘NUMBER2’’, 
“АУЕКАСЕ” 
60 PRINT A,B,(A + B)/2 
The display is: 


AVERAGE 8.16 
МІ/МВЕК1 NUMBER2 
AVERAGE 

7.65 8.67 

8.16 


Clearly the comma is useful if we wish to print a table with two 
columns, but is unsuitable if we wish to have a table with more than 
two columns. 


It is important to remember the screen size when deciding the 
form of your output. For your output the effective screen is 22 
lines each 32 columns wide. 


TAB 


TAB C; moves the print position to column C. If this would 
involve back-spacing it moves on to the next line. 


The following program (with printout) indicates how the TAB function 
can be used to improve the presentation of results. 


10 LET А$ = “А.В.ЈОМЕЅ” 

20 LET B= 65 

30 PRINT “NAME”;TAB 6;A$; TAB 19:“АСЕ”: 
TAB 23;B;TAB 27; “YEARS” 


NAME A.B.JONES AGE 65 YEARS 


Note the semi-colons between TABs and print items. It is important to 
remember that each line has 32 columns, numbered 0 to 31. 
The next program shows a simple way of tabulating results. 


10 PRINT “МО.”;ТАВ 4;“5ОСАКЕ”;ТАВ 12; 
“СІУВЕ”;ТАВ 20;*RECIP" 

20 INPUT N 

30 PRINT N;TAB 4;N*N;TAB 12;N*N*N; 
TAB 20;1/N 

40 GOTO 20 


101 





NO. SOUARE CUBE RECIP 

1 1 1 1 

2 4 8 0.5 

3 9 9/ 033333333 
4 16 64 0.25 

5 25 125 0.2 

6 36 216 @.16666667 
7 49 242 0.14285714 
8 64 512 0.125 

9 81 729 0.11111111 
10 100 1000 0.1 


It is important to remember that numbers are output with up to 8 
figures and allow the appropriate space. An alternative is to decide how 
many figures you want and use the INT function (see Section J). 


I3: PRINT AT 


AT L, C moves the print position to line L and column C. 


For example: 

10 PRINT AT 10,12“ CENTRE" 
will cause the string specified to be printed starting at line 10, column 
12, i.e. roughly in the centre of the screen - since L goes from 0 to 21, 
counting down the screen, and C goes from 0 to 31, counting left to 
right. 


EXAMPLE 


The program below sets up a symmetrical pattern using the character 
of your choice. Note the use of the command CLS to clear the screen of 
your input. 


10 PRINT AT 5,4;"WHICH CHARACTER?" 
20 INPUT AŠ 

30 CLS 

40 LET L=INT (RND*10)+1 

50 LET C=INT (RND*15)+1 

60 PRINT AT 11%,,164С;А65 

70 PRINT АТ 11-L,16-C;A$ 

80 PRINT AT 114L,16-C;A$ 

90 PRINT AT 11-L,16+C;A$ 
100 GOTO 20 


Try adjusting the parameters in lines 60-100. 
The important feature to remember is: 


Number of character cells is 32 horizontally by 22 vertically, 
i.e. 32 x 22 altogether. 


The TAB function uses C = @ to 31 only. 

The AT function uses L = 0 to 21 

and C = 0 to 31. 

You should have noticed that the PRINT commands reinforce each 
other, and provide alternative ways of achieving the aim of placing 
characters, character strings or numbers at the desired positions on the 
22 line, 32 column screen display. 

For example, these three programs: 


19 LET X = 3 
20 PRINT X,,;, 
30 PRINT X*X 


10 LET X = 3 
20 PRINT X 
30 PRINT 

40 PRINT X*X 


10 LET X= 3 
20 PRINT X,TAB 32;" "TAB 32;X*X 


would give the same printout on screen. The number of keystrokes 
(count them) is what determines which statement usage is efficient in 
any instance. You will soon come to recognise which to use if you 
experiment. 


PRINT AT instructions will overprint anything already printed at 
the position specified. We can use this to replace on the screen one set 
of data, or one string, by another. 


10 INPUT X 
20 PRINT AT 0,0;X 
30 GOTO 10 


overprints one X by the next X each time. If we input 1,2,3...10 it 
works fine. But if we input 10,9,8...1 we get: 


etc. 
Similarly, 


ZU ЕТТІ” 


40 PRINT AT 10, 10; “SINCLAIR” 
works, but not if we swap the two strings around - we end up with 
ZX81LAIR, and we have the same problem with numbers, which can 
be between one and eight digits long. 
We can blank out something on the screen by overprinting an empty 
string. For the simple problems above, the addition of appropriate 


103 


strings will work; we add 4 spaces after “27Х81”, so that line 10 
becomes: 

10 PRINT AT 10,10; “ZX81 E 
and for numbers, we can use: 

20 PRINT AT 0,0;X; *“ id (7 spaces) 
Using LPRINT also requires care. 


For the LPRINT instruction, TAB works exactly as PRINT 
TAB. 
LPRINT AT L,C is converted to LPRINT TAB C, and the 


line number is ignored. 


This is because the printer cannot go back to a previous line. Try this 
program. Input 1,2,3,4,5. 


10 INPUT X 
20 LPRINT AT X,X;X 
30 GOTO 10 


will print 12345, as if line 20 had read LPRINT TAB X;X. 

For any programmed screen format that 1s not a simple sequence of 
print lines, it is better to use COPY to produce output on the printer, 
once all the data is on the screen. 


COPY prints the entire current screen display on the printer. 


If used as direct command, we can COPY less than a whole screen by 
pressing BREAK before completion, but if used in a program, the 
whole screen will be copied. 


14: The Graphics Characters оп the ZX81* 


The ZX81 character set includes a set of graphics characters, and you 
were told how to access them in Section B. To recap: 


Graphics characters are accessed by using |Graphics| to get 
the cursor. Repeat to return to cursor. Unshifted keys 
then produce inverse video characters. (e.g. key Q gives |.) 
Shifted keys produce graphics cells, if shown on the keys: e.g. 
SHIFT R gives "W .If no graphics cell is shown, result is 
inverse video form of normal shifted character (e.g. SHIFT U 


gives В ). 


The inverse video characters and graphics cells can be used for 
enhancing displays and drawing bar charts, diagrams and pictures. 
They are manipulated as strings, by putting quotes round them, e.g. 
PRINT “ ER or PRINT “ B”. 


* The Spectrum offers more extensive graphics facilities than the ZX81, and Spectrum 
owners should refer to Unit W3 for details. The Spectrum has the solid graphics 
characters of the ZX81, but not the shaded characters, on keys 1 to 8 in graphics mode. 
Read through this section bearing this in mind. 


104 


Put your computer in graphics mode and run through the keyboard, 
noting the unshifted and shifted versions of each key. Note that 
RUBOUT (DELETE) works with the cursor, but the cursor 
control keys do not, and that the cursor must be on screen for them 
to work. 

By the time you fill one line and move on to the next, you will see 
that all these graphics characters Join up, with no gaps between the 
cells. The difference between the grey cells on the A and K keys is that 
they Join up with the half-shaded graphics cells on the S, D, F and G 
keys in different ways. Experiment with these. If they join up properly, 
you cannot see the Join. If they do not, the Join is visible as a chequered 
pattern. To check the characters across the screen, use the bottom lines 
of the screen directly. To check the vertical Joins, enter this program: 


10 INPUT A$ 
20 PRINT A$ 
30 GOTO 10 


Change the cursor to [G], then input the graphics character. You 
have to then press NEWLINE (ENTER) twice; the first time to change 
to [L], the second to input the character. 

We can use the graphics characters to draw (crude!) pictures, 
enhance printout on the screen — by printing prompts in inverse video 
for example —or putting titles inside surrounds, and use them in 
diagrams or moving graphics. You'll have to wait a few more chapters 
before we can do anything interesting, but here are a few things to try: 
Here’s a program to put a border round a word in inverse video. 
Notice we store the graphics in string variables. This gives us better 
manipulative power than if we just used literal strings. On the ZX81 
the graphics characters in A$ are the shift graphic on the E key, 11 
times the one on the 7 key and the one on the R key. If you are using a 
Spectrum, the relevant keys are ‘4’, ‘3’ and ‘7’. You can work the 
other lines out for yourself. 


A 


s 
ie 
zu 
зә 
46 i 
се 

e 





Notice the combined PRINT AT statements in line 60. 

The production of inverse characters on the Spectrum (white 
characters on a black background, unless colour is being used) can be 
done in different ways. You can use CAPS SHIFT and the 4 key to put 
an INVerse VIDEO control character before a letter or other 
character, but this will make a// characters thereafter into their inverse 
forms unless CAPS SHIFT and 3 is used to restore NORMAL 
VIDEO. The alternative is to use INVERSE as part of a program 


105 


statement. INVERSE is obtained using SYMBOL SHIFT and the M 
key in E mode. To get inverse video this must be followed by 1, so that 
to print HELLO in inverse video we key in: 

10 PRINT INVERSE 1; "HELLO"' 
This will appear normally in the program listing, but in inverse when 
the instruction is carried out. 

Now add the following lines, and you will see why the use of string 
variables, and variables for the line and column numbers, can be 
useful. 

70 LET X=X+1 
80 LET Y=Y+1 
90 CLS 
100 GOTO 60 
Run the program, and you see we have a crude moving display. CLS 
makes the screen ‘flash’ a bit, but we could avoid this by overprinting. 
Revise the program to erase by overprinting empty strings. 

We can use the graphics characters for pictures. Try this: 

10 PRINT AT 0,9; “аша ` _ 
20 PRINT AT 1,8; === = 
30 PRINT AT 2,8; “ "EE" 


(it’s supposed to be а car). 





Change the program to allow you to input a value for Line and 
Column numbers, so that you can place the car in different places. 
Then add a GOTO loop to allow multiple cars on the screen. 


Exercises 


1 Write a program that puts: 


ADDRESS: 





on the screen, then prompts for inputs on line 20 (INPUT 
NAME etc), and prints the responses on the screen. 

Each prompt should overprint the previous one. Allow four 
separate lines for the address. Blank out the last prompt, then 
have the screen copied on the printer. 


106 


Add a routine to LPRINT name, address and age, without the 
borders or titles, on the printer after deleting the COPY 
Instruction. 

Input names, ages and occupations of three friends and arrange 
them to be tabulated in a suitable form. 

Experiment with ways to make the car move across the screen. 


107 


SECTION J: ARITHMETIC AND FUNCTIONS 


Ji: Arithmetic Operations 


A prime function of the computer is to evaluate formulae and 
expressions similar to those used in standard mathematical calculation. 

Algebraic EXPRESSIONS are written in BASIC using the 
following OPERATORS with a set of variables or numbers as the 
OPERANDS. 


ARITHMETIC OPERATOR EXAMPLE 
SYMBOL NAME PRIORITY BASIC MATHS 

in exponentiation 10 А**3 А? 

(raising to a power) 
[^1] (on the Spectrum) А13 A? 

- negation 9 -А -А 

и multiplication 8 A*B AxB (a.b) 

/ division 8 A/B A+B e 

+ addition 6 A+B A+B 

_ subtraction 6 А-В А-В 


Note that negation operates on one operand ~ a unary operation ( i.e. 
makes a variable negative, e.g. — A) and that the subtraction operator 
uses two operands, e.g. А-В, a binary operation. 


J2: Priority 


1 All arithmetic, conditional and logical operations are assigned a 
priority number from 10 to 1. High priority is 10, low priority is 
1. The priority numbers for the arithmetic operators are as 
shown in the previous Unit. 

2 The priority of an operation determines the order in which it is 
evaluated in a complex statement in which more than one 
operation is to be performed. High priority operations are 
performed earlier. 

3 Brackets (parentheses) are used in BASIC algebraic expressions. 
Brackets clarify which expressions constitute separate values to 
be operated on. Expressions inside brackets are evaluated first 
before the quantity is used in further computation. With multiple 
(nested) brackets the evaluation proceeds from the innermost 
bracketed expression to the outermost. 

4 For operations of equal priority in the same statement, 
evaluation is from Left to Right. 


Brackets can often be omitted when the sequence of evaluation is 


108 


understood, but there is no harm in using them to ensure correct 
evaluation. Expressions may be tested by using PRINT as a direct 
command, to check that you have them correct. For instance key in 
PRINT (8*2.6/5)*2/3 and press NEWLINE (ENTER). The result will 
be printed on the screen. If a sequence of direct assignments of values 
to variables is keyed in first (using LET A = 4 (NEWLINE/ENTER), 
LET B = 3 (NEWLINE/ENTER), etc.) then variable expressions may 
be evaluated. 

Using this facility you should experiment with a variety of 
expressions until you feel confident that you have understood the way 
in which expressions are evaluated, and the way you have to formulate 
an expression in BASIC to ensure it returns the desired result. 


EXAMPLES 


1 Evaluation ofa+b-c 
In BASIC: A+B-C 
Operators have equal priority; 
(1) Left to Right A+B 
(2) L-*EK (A+B)-C 


2 Evaluation of ab , (axb) +c 


In BASIC A*B/C 
* has same priority as / 

H LR A*B 
(2) L*R (A*B)/C 


3 Evaluation of a.(2) ‚ах (b+c) 


In BASIC A*(B/C) 
(1) Brackets first (B/C) 
(2 Multiplication — A*(B/C) 


But notice we could write the expression without brackets in 


BASIC as B/C*A 
This is evaluated: 

H LR (B/C) 
(2) L= Е (B/C)*A 


which gives the correct result. 


4 Evaluation of (b° - 6c)*+5 


In ZX81 BASIC notation: (B**2 = GG )**24 5 
(1) Inside bracket; 
exponentiation B**2 
(2) Inside bracket; 
multiplication 6*C 
(3) Inside bracket; 
subtraction (B**2) - (6*C) 


109 


(4) 
(5) 


Exponentiation ((B**2) - (6*C))**2 
Addition (((B**2) – (6*C))**2) +5 


In Spectrum BASIC notation: (B 2 - 6*C )#2+5 


(1) 
(2) 
(3) 


(4) 
(9) 


Inside bracket; 

exponentiation Bez 

Inside bracket; 6*C 
multiplication 

Inside bracket; 

subtraction (В%2)-(6“С) 
Exponentiation (В t 2). – (6*C))4 2 
Addition (((B f 2) – (6*С)) # 2) +5 


2 
Computer evaluation of a.b- © + (e - f) 


d g 

In ZX81 BASIC notation: A*B - C**3/D +(E-F)/G 
(1) brackets E- 
(2) exponentiation Er 
(3) multiplication/ 

division L — R А“В  C'"3/D (Е-ЕУС 
(4) addition/ 

subtraction L > R (A*B) - (C**3/D) + (Е – Е)/С 
In Spectrum BASIC notation: А*В - С \ 3/0 +(E-F)/G 
(1) brackets Е-Е 
(2) exponentiation OTs 
(3) multiplication/ 

division L > R A'B Ct3/D (E-FyG 
(4) addition/ 

subtraction L > R (A*B) - (C ^3/D) + (E - FG 
Evaluation of —70 +2х ^ x3-3x7 
In ZX81 BASIC notation: 40 +2 "4702 "3.8." 
Priority 10 4#**2 

16 

Priority 9 - 70 
Negation 
Priority 8 2°. te *23 377 
LR 96 1 
Priority 6 - 70 + 96 — Д1 
Result 5 
In Spectrum BASIC -70 +2*442*3-3%*7 
Priority 10 412 


16 


110 


Priority 9 - 70 


Negation 
Priority 8 2> 15 "TET 
L — R 96 21 
Priority 6 - 70 + 96 - 21 
Result 9 

Exercises 


1 Write the order in which the following BASIC expression 1s 


evaluated: 
— А + ((B**3/C) - (A**2/D))*(E + Е)/С (ZX81) 
— А + ((B 13/C)- (A ^ 2/D))*(E+ F/G (Spectrum) 


2 Write down the BASIC expressions for: 


(i) (и? + 2аѕ)^ 

(ii) ut + Тағ 

жа b + ac)" 

(111) 2a 

(iv) (xy 

Work out the order in which each of the expressions is 
evaluated. Test your results on the computer. 


J3: Number 


À positive or negative decimal number whose magnitude is 
between an approximate minimum of: 
t3x10 ? 
and an approximate maximum of: 
+2 x 10” 
Zero is included in this range. 
The smallest number the computer can handle is 
2.9387359 x 10 `” 
The largest is: 
1.7014118 x 10° 
The computer stores and calculates numbers internally to an 
accuracy of nine or ten digits, but prints out the results of 
calculations to eight significant figures only, rounding where 
necessary. 


J4: The E Notation 


The E or EXPONENT or scientific notation is the notation 
computers use for input and output of numbers having a large 


111 


number of decimal digits. E should be taken to read: ‘times 
ten to the power of’. For example: 
1.73 E5 
is 
1.73 times 10 to the power of 5 
1.73%10%%5  (1.73*10 ^ 5 in Spectrum notation) 
= 173000. 
Similarly: 


3.8E-7 
is 
3.8 times 10 to the power of — 7 

= 3.8*10** 7 (3.8*10 41 — 7 in Spectrum notation) 

= .00000038. 
The computer will accept any number keyed-in in this form 
and will print out numbers in this notation when their values 
are outside a certain range. 


For large positive and negative numbers the E notation is 
automatically used by the computer for numbers 
> = 10? 
Numbers up to this figure are first rounded to 8 significant figures and 
trailing zeros are added until 107 is reached. 
Key in and run this program: 


10 LET A = 9.9999993E12 


20 PRINT A 
30 ІЕТА =А + 1Е5 
40 СОТО 20 


Change line 20 to read: 
| 20 LPRINT TAB 10;A 
to get a listing of the result on the printer. 
For small positive and negative numbers the E notation is 
automatically used for numbers: 
<= 10^? 
To see this in action, key in and run the program below: 


10 LET A-1.000001E — 5 


20 PRINT A 
30 LETA-A -(1E- 12) 
40 GOTO 20 


Change line 20 to: 
20 LPRINT TAB 10;A 


if you want a printer listing of the changeover. 
Exercises 
1 Key in and run the following simple program, which illustrates 


how numbers are printed, the E notation and the largest number 
which may be obtained. 


112 


10 LETA=1 

20 LET A=A*10 

30 PRINT A 

40 GOTO 20 
With the ZX81 press and when 
the screen becomes full, and the message 5/30 appears on the 
bottom of the screen to indicate no more room on the screen. 
The Spectrum will display the ‘scroll?’ prompt. 

Notice the change to the E notation. Note that the program 
finally stops itself on the ZX81 with the error message ‘6/20’, 
which indicates an arithmetic overflow (error code 6) as a result 
of line 20, i.e. the number is too large for the computer to 
handle. The Spectrum's response is more precise; the error code 
in this instance will read: ‘6 Number too big, 20:1’. 

Change line 10 of the program to each of the following and run 
the program each time. 

a) 10 LET A=1.00000000 

b) 10 LET A=1.1111111 

c) 10 LET A=1.7 

d) 10 LET A=1.7014118 

e) 10 LET A =1.71 
What conclusion do you draw? 
To show that negative numbers behave in the same way, change 
line 1@ to the following and run the program. 

a) 10 LET A= -1 

b 10 LET A= -1.7 

c) 10 LET A= -1.7014118 

d) 10 LET A= -1.71 
To show how small numbers are handled by your computer a 
similar program divides a number (A) by increasing powers of 
10. 


Key in the program and run it. 


10 LET A=1 
20 LET A=A/10 
30 PRINT A 
40 GOTO 20 


Note the change of notation. 

Notice that after 1E – 38 the computer prints zeros 
indefinitely, i.e. it has reached the smallest number it can 
register. 

Change line 10 to 
а) 10 LETA=3 
Ы) 10 ІЕТА = 2.9 
апа ге-гип the program each time. 

Notice that 2.9387359 E — 39 is the smallest number before 
zero. 

Write this number out in full. 

Can you think of any applications for very large and very 
small numbers? 


113 





6 Change the values of À in the program to negative values and 
confirm that small negative numbers behave in the same way. 


PROGRAMS TO SAVE IN YOUR TAPE LIBRARY 


The following two programs should be keyed in, run, listed and saved 
for your tape library. They both do what the previous programs did but 
in addition give a printed copy of the results. 


10 REM "LARGE NUMBERS" 

20 REM** PROGRAM MULTIPLIES + 
AND - NUMBERS INPUT FROM 
THE KEYBOARD BY POWERS O 
F 10 ** 

30 REM **KEY IN VALUES FOR A O 
P +-1,,4-1.1111111,4-1..7,. + 
-1.7014118,%- 1.71.** 

40 INPUT A 

50 LET N=0 

60 PRINT А%(10%%у) 

70 LPRINT TAB 10;A*(10**N) 

80 LET N=N+1 

90 GOTO 60 


For the Spectrum, replace ** by in lines 60 and 70. 


10 REM "SMALL NUMBERS" 

28 REM**PROGRAM SHOWS PRINTING 
OF SMALL NUMBERS** 

30 REM**INPUT VALUES OF A AS + 
-1, +-2.9,+-3.** 

40 INPUT A 

50 LET N=0 

60 PRINT A*(10**N) 

70 LPRINT TAB 10;A*(lQ**N) 

80 LET М-М-1 

99 GOTO 60 


J5: Rounding 


ROUNDING UP 


The computer will print out computed values to an accuracy 
of 8 significant figures, ignoring leading zeros. 

Digits after the 8th significant one will be rounded up. For 
example, if we key in (as a direct command, followed by 
NEWLINE/ENTER): 


11% 


PRINT 0.111111111 + 0.888888888 
the answer on the screen is 1.Try 
PRINT 0.0000111111 
showing 10 digits can be held exactly. 
Adding a one on the end forces the use of the E notation. 


ROUNDING DOWN 


The INT function returns the nearest integer of the 
expression X, which is < = X, i.e. it rounds down. 
e.g. INT 3.9= 3 

INT -2.8- -3 

INT (4 -8.7 +0.8)= - 4 
Try printing these functions. Notice that for negative 
numbers - 6 is less than - 5, and so on. To round to the 
nearest integer add 0.5 to the number first: 
e.g. INT (3.9+0.5) = 4 

INT (2.4 + 0.5) 2 

ІМТ(-1.7-0.5)- -2 

ІМТ(-2.3-0.5)- -2 
Notice this assumes that 0.5 rounds (о 1. 

INT (1.5-0.5) = 2 

INT (-1.5+0.5)= -1 


Notice we don’t have to enter the zero before the decimal point on the 
computer (though it doesn’t matter if we do), it’s in that form here for 
clarity. 


J6: How Numbers are Handled 


All computers perform their arithmetic and processing using 
the BINARY NUMBER SYSTEM 


In the binary system only two digits are used, 1 and 0. A group of 8 
binary digits (bits) is called a BYTE, and we communicate with the 
computer in Decimal Notation. This is rather more convenient than 
using Binary. Conversion from Decimal to Binary and vice versa is 
thus necessary and occurs inside the computer. 

One BYTE is equivalent to a single character of the computer’s 
character set. A byte represents a number between 0 апа 255 
(decimal). ‘This is why the character codes are in this range (see Section 
P). A group of 8 zeros and ones can have 2° ( = 256) different states. 

A digit or number is represented by one or several bytes according to 
its context in the computer. 


115 





A character input to the computer or output to the screen or printer 
is held in one byte. Program line numbers, which are whole numbers 1 
to 9999, are held in two bytes. 

Numbers are held in a form which occupies five bytes. The point to 
be noted here is that conversion from decimal to binary and back is 
involved in the operation of the computer, and this conversion is not 
always exact. This must be allowed for in certain circumstances, 
especially where the computer is asked to check whether two numbers 
are equal. A difference in the binary form of the number, however small, 
will cause the computer to decide they are not equal. In testing two 
numbers for equality, therefore, if non-integer values have been 
utilised, and the value of one number arrived at by calculation, the 
equivalence check should be replaced by assessing the difference. A 
statement such as: 

IF ABS(A - В) < 1E-4 THEN... 
which checks that the difference between the numbers is less than 
.0001, сап be used instead of IF = B THEN ...., if either A or B has 
been calculated. 

The forms in which numbers are held in the computer are 
considered in detail in Section U — the Computer Memory. 


J7: Function 


We define a FUNCTION as 
Y = F(X) 
‘Y equals some function of X, F(X)’ 
A function is the mathematical relationship between two 
variables X and Y such that for each value of X there is a 
unique value of Y. 


Y takes the function value and is the DEPENDENT VARIABLE. 
X is the ARGUMENT - the INDEPENDENT VARIABLE. 
F is the function NAME, e.g. square root, sine, natural logarithm. 
In a program statement we write, for example: 
100 LET Y  SOR(X) 
The argument X can be a single variable, a number or an expression. 
If X is a single variable or a number it does not need brackets. If it is an 
expression it requires brackets so that the expression is evaluated 
before the function is applied to it (so that SOR 9 + 7 gives 10, whilst 
SOR (9 + 7) gives 4). For example: 
100 LET Y = SOR 9 
100 LET Y = SOR(B**2—4*A*C) (B42 on the Spectrum) 
We see that a function is a mathematical operation which gives a 
number. It is treated in BASIC as a numeric expression, with priority 
I. 


116 


The standard mathematical and trigonometric functions are 
important timesavers for programmers. They are the same as the 
function keys on scientific calculators. Other functions (utility 
functions) control or monitor the handling of data by BASIC rather 
than perform mathematics. 

If the functions were not available in BASIC we would need to write 
separate programs to undertake their tasks every time we had need of 
them! 


J8: List of Functions used in Sinclair BASIC 


In this list of functions X is the argument. X is a variable, a number or 
an expression. If an expression, X must be in brackets. Each of the 
individual functions will be discussed in more detail later in this 
section. 


1. Standard Mathematical Functions: 
ABS (X) - gives the absolute value of X 
EXP (X) - gives e", value of e raised to the power X 
INT (X) -gives the largest integer < = X, i.e. rounds down 
LN (X) -gives natural logarithm (value of log. X) 
SOR (X) -value of V X or X* (X positive) 
PI -3.14159265 i.e. value of n, PI, which is how it 
prints on screen 
SGN (X) -gives sign of X, i.e. whether X is + ve, – ve or 


Zero. 


2. Trigonometric Functions 

SIN (Х) - value of sine X (X in radians) 

COS (X) -value of cosine X (X in radians) 

TAN (X) -value of tangent X (X in radians) 

ACS (X) -angle in radians whose cosine is X 
-arccosine Х( - 1 «- X < = 1) 

ASN (X) -angle in radians whose sine 18 X 
-arcsine X ( -1 <= X < = 1) 

АТМ (X) -angle in radians whose tangent is X 
- arctangent X 


3. Special Mathematical Functions 

RND A random number generating function; gives the 
next pseudo random number N from a fixed series 
of random numbers (0 < = N < 1). 

RAND ( RAND 0) starts the sequence of random 
numbers in an unknown position. 

RAND N (ü0 < = N < = 65535) makes RND always return to 
the same value, if N is the same. 


117 





4. Character and String Functions 


CHR$(X) 0<-Х <=255 returns the single character 
whose code is X. 
CODE A$ When applied to the string A$, it returns the 


code of the first character in the string or 0 if the 
string is empty (null string). 

LEN A$ Returns the number of characters in the string. 

VAL A$ Turns a string in number representation into 
the number for calculation (e.g. A$ = “12.4”, 
VAL А$ = 12.4). 

STR$ М Turns the number N into the string “N”. 


5. Printing Functions used in the form PRINT F(X) 


TAB (X) Places the print position in column X. If X>32 
then column number is the remainder when X is 
divided by 32. If it involves back spacing, goes 
on to next line. Rounds X to nearest integer. 

AT (X), (Y) Starts printing at line X, column Y 
бжделлбе21. = Y <= 31 


Rounds X and Y to nearest integer. 


6. Special Functions 

INKEY$ No argument. Reads keyboard and senses what 
key is being pressed at that time. Returns key 
being pressed as a string, e.g. “А” or ‘‘8’’. If no 
key is pressed the null string is returned. 

PEEK X 0 < = X < = 65535 Returns the value of the byte 
at address X in RAM or ROM memory. 

USR N Returns the contents of a pair of CPU registers 
after running a machine code program from 
address N. 


N.B. For the Spectrum’s additional functions, see Section W. The 
above functions, common to both the ZX81 and the Spectrum, are the 
ones used in the main body of the text. 


J9: The Function Characters 


Each of the functions in Sinclair BASIC is represented on the 
keyboard as a single character word. 

You don’t have to type the function name letter by letter (if 
you try to it won’t work), just press the particular function 
key. 

Each function character has a special character code and is 
part of the computer’s character set. Each of the Function 


118 


characters on the ZX81 is situated at the same position on 
each key, i.e. bottom outside. 

To obtain the function the ZX81 must be im FUNCTION 
MODE, with the F-cursor on the screen. 

On the Spectrum, all functions are obtained in the 
Extended mode with the E-cursor on the screen (for further 
details see Section W1). All FUNCTIONS treated here are in 
green above the key on the Spectrum, with the exception of 
ASN, ACS, ATN which are in red below the associated SIN, 
COS and TAN functions, although they are still obtained in 
the E-mode. 

The FUNCTION/EXTENDED MODE only lasts for one 
function. To obtain successive functions this mode must be 
repeatedly entered. 


J10: The Function Character Set 


Character Code Code 
(7Х81) (Spectrum) 
SIN 199 178 
COS 200 179 
TAN 201 180 
INT 207 186 
RAND 64 249 
STR$ 213 193 
CHR$ 214 194 
CODE 196 175 
PEEK 211 190 
TAB 194 173 
ASN 202 181 
ACS 203 182 
ATN 204 183 
SGN 209 188 
ABS 210 189 
SQR 208 187 
VAL 197 176 
LEN 198 177 
USR 212 192 
LN 205 184 
EXP 206 185 
AT 193 172 
INKEY$ 65 166 
NOT 215 195 


п (PI) 66 167 


These are the function characters as represented on the ZX81 
keyboard. NOT is dealt with in Section R and INKEYS in Section K. 
Note that ARCSIN, ARCCOS and ARCTAN are used on the ZX81 
keyboard but print as ASN, ACS, АТМ, and п prints as РІ. 


J11: The Standard Mathematical Functions 


ABS (X) 


Returns the absolute value or modulus of the value X. 
X may be a number, variable or expression. 
ABS(X) gives us the positive value of X. For example: 
10 PRINT ABS( - 3.7) gives 3.7 
10 PRINT ABS (4) gives 4 


Exercises 


Key in and run this program: 
10 INPUT A 
20 INPUT B 
30 PRINT TAB 3;A; TAB 10;B 
40 PRINT TAB 3; ABS (A - B) 
30 GOTO 10 
Input positive and negative values for A and B. 
Now change line 40 to: 
40 PRINT TAB 3; ABS (A*B) 
and input some more values. Try replacing the * with ** 
( ^ Spectrum), or using ABS (SOR А). 
N.B. ABS (- 3**3) , or expressions in similar form will not work 
as the ** ( ^ Spectrum) operator only works for positive first operands. 


EXP (X) 


Where X is a number or an expression EXP (X) gives the 
value of the constant e raised to the power of the value of X 
e — 2.7183 
e.g. 10 PRINT EXP (3.4) 
i.e. 10 PRINT (2.7183* *3.4) (2.7183 1 3.4 on Spectrum) 
The function EXP is the inverse to LN. 


Exercises 


1 Using log tables write a program to check the values of e* given 
in the log tables. 


120 


2 Write a program which will calculate O from the expression: 
Q = Qo.e-"* (In BASIC Q = QO* ЕХР(-Т/К“С)) 
If you know anything about electricity, you might recognise this 
expression. 
3 Key in this program. It calculates a value for e from the formula: 
e=(1+1/N)**N (^N оп Spectrum) 
where N is very large. Spectrum users should replace ** by # in 


lines 30 апа 40. 


10 REM “VALUE OF E" 

20 ІЕТІ- 1 

30 LET N=10**I [^Spectrum] 
40 LET E=(1+1/N)**N 

50 PRINT TAB 1;N;TAB 12;E 
60 LET I=I1+1 

70 IF l=5 THEN STOP 

80 GOTO 30 


LN (X) 


Gives the value of the natural logarithm. 
LN (X) = Log, (x) 
Note that log, (X) (common logarithm) 
= ( LN(X) )/( LN 10 ) 
The LN function is the inverse of EXP 
So: If EXP (X) = Y 
Then (X) = LN(Y). 


LN (Y) is the natural logarithm of Y. The antilog is EXP(LN(Y)). The 
normal log operations can be used if appropriate, as with common logs. 


For example EXP(LN (X) + LN (Y)) gives the product of X and Y. 
Exercises 


1 10 LEFY=1 
20 PRINT TAB 3;Y; TAB 10; ЕХР (LN Y) 
30 LET Y=Y+1 
40 GOTO 20 
Key in and run this program which proves the relationship 
between the EXP and LN functions. 
2 Change 30 to: 30 LET Y = Y*1@ and run again. 


SQR (X) 


The function SQR returns the square root of (X), V (X) or 
Х95, For example: 


121 


PRINT SQR 9 gives 3 
PRINT SQR 23 gives 4.7958315 
PRINT SQR (19 + 17) gives 6 
PRINT SOR (ABS - 25) gives 5 


SGN (X) 


SGN (X) returns + 1 if (X) is positive, 0 if (X) is zero, — 1 if 
(X) is negative. 

SGN is short for Sign or Signum (Signum doesn’t sound like 
Sine). For example: 


SGN 23 gives 1 

SGN - 5 gives - 1 

SGN (3 – 3) gives Q 

SGN 1 gives 1 

SGN (25 - (2*23)) gives — 1 
п PI 


T (which prints on the screen as PI) is a function which has no 
argument. It returns the value of r as 3.1415927. 


3.1415927 is what prints on screen for PI. How would you test whether 
the computer held any more digits of PI in memory? What happens 
when you take away 3 from PI? 


J12: Trigonometric Functions 


SIN COS TAN 


The functions SIN (X), COS(X)and TAN(X) give the value of 
the sine, cosine, and tangent of the number or expression X, 
which is an angular measure. X must be in RADIANS. 
We normally express angles in DEGREES. 
PI 


= өй. 9... dE. Š 
1 DEGREE 180 RADIANS (1 180 radians) 


To convert degrees to radians multiply by PI/180. For 
example, if Y is our measure of angle in degrees then: 
SIN (Y*PI/180) 


gives the correct value of Sine Y. 


Exercises 
1 Generate a table of values for SIN (X), COS (X) and TAN (X) 


122 


for every 20 degrees in the range 0 — 360 degrees. 
2 Write a program to verify the trigonometric formula: 
SIN(XX)+COSXX) =1 
1+ TAN XX) =SEC*X) 
3 Write a program to calculate the area of a triangle from a 
knowledge of the length of 3 sides and an angle. 


ACS ASN ATN 


The functions: 
ACS (X), ASN (X), ATN (X) 

give the arc cosine, the arc sine and the arc tangent, 
respectively, of (X). 

The returned value is the angle in RADIANS for which the 
cosine, sine or tangent would be given by the value of (X). 

To get the angle in degrees multiply by 180/PI e.g. 
Y = 180/PI*ACS(X) gives arcsin (X) in degrees. 


Notice these functions print as above, but appear on the ZX81 


keyboard as ARCSIN, ARCCOS, ARCTAN. 
J13: Special Functions 


Random number generators are useful for games and simulation in 
statistics. The numbers generated are part of a very long sequence of 
numbers (there are 65536 of them) and are in fact only ‘pseudo- 
random’, but good enough for our needs. 


RND 


RND gives a random number greater or equal to zero but less 


than one. 
10 LET A = RND 


assigns a number in the range 0 < = N <1 to the variable A. 
Notice RND has no argument. 


If we key in PRINT RND we get a number like .0011251904 or 
0.43715682 which is eight or ten digits long and is not much use to 


anybody in this form. 
We need to be able to generate random numbers within a useful 


range, according to our purposes: 


1. To obtain a Random Number 0 - 9 
To obtain a random number from 0-9 we must multiply our 


123 


function by 10 and take the integer value. 
i.e. PRINT INT (RND*10) 
RND*10 gives random numbers between 0.00000000 and 


9.9999999, IN'T( ) will round these values down to integers 
0 to 9. 


2. Numbers 1-10 


Although @ to 9 gives us ten values the range 1 to 10 would be 
more useful. This is obtained by adding one to the RND function: 
PRINT INT (RND*10 + 1) 

Suppose we wanted random numbers generated for simulating a 

dice roll, we would use: 


PRINT INT (RND*6 + 1) 


3. Random Numbers for a Card Game 


There are 4 suits, with 13 cards per suit = 52 cards. So if we used: 
PRINT INT (RND*52 + 1) 
we could select cards at random. 
Think about how you could identify the suits and not deal the 
same card twice. 


4. ‘Tossing a Coin 
There are two outcomes, head or tails, so: 
10 LET A= INT(RND"?2 + 1) 
20 IF A=1 THEN GOTO 50 
aD PRINT “TAILS” 


40 GOTO 10 
50 PRINT “HEADS” 
60 GOTO 10 


This program will toss coins until we use BREAK. 


RAND N 


RAND is a keyword and is used for controlling the 
randomness of RND. 

The computer has a fixed sequence of 65536 jumbled up 
numbers. RAND N will start RND reading numbers from the 


Nth number in the sequence. 


Key in and run this program to prove the above: 
10 RAND 7 
20 LET Ce=1 
30 PRINT RND 
40 LET C-C-«1 


124 


50 IF C<6 THEN GOTO 30 
60 GOTO 10 


Not amazingly random after all! 
Exercises 


1 Write a program which throws three dice and prints the values 
thrown across the screen. 

2 Write a program to check that the number generated by RND 
using RAND N is given by RND = (75*(N + 1) - 1/65536). 

3 Modify the coin tossing program to count the number of times 
heads or tails have come up (you need one variable for each). 
When you've stopped the program by pressing BREAK, you 
can then access the values by keying in PRINT HEADS, or 
whatever your variable name is, as a direct command. 

4 Write a program to print four groups of three random numbers 
in the range 1 to 52. 


125 


SECTION K: STRINGS 
K1: Strings 


A string is a set of characters enclosed by quotation marks, 
e.g. “THIS IS A STRING” or the null string (no characters 
Typical Strings: “BALL OF STRING" 

“JANUARY 1ST 1982” 

“URGHH!” 

“FAB ** — +/!3” 

E " (String of spaces) 

1234” 

ore (Null string) 


Computers handle two kinds of DATA: 
NUMERIC - numbers 
ALPHANUMERIC - names or TEXT. 
The way a computer deals with text is called STRING HANDLING. 
Strings deal with ALPHANUMERIC information. 

The sequence of alphanumeric characters is handled in a string as a 
single unit of data. 

Characters are defined as LITERALS when placed inside quotes 
“> They are taken literally to represent themselves. Strings are 
therefore literals. 

Characters are IDENTIFIERS where they are not enclosed in 
quotes. Thus, for example, A represents or identifies a numeric 
variable and A$ identifies a string variable. 

Strings can either be of FIXED LENGTH-e.g. always 10 
characters long - or VARIABLE LENGTH. The fixed length is 
determined by the string dimension instruction: 

DIM A$ (N) 
where N is the length in characters. 


Characters which cannot be used in strings 
A string cannot contain a character that is a line terminator: 
NEWLINE (ENTER) or TAB. Nor can it contain any of the 
following: 

EDIT 

GRAPHICS 

RUBOUT (DELETE) 

FUNCTION 

BREAK 


ee 


(single quotes) 


126 


All other characters in your computer’s character set can be used. 
Run the program which checks this: 


10 INPUT A$ 
20 PRINT A$ 
30 GOTO 10 


Now try and input some of the above characters. 
Examples of the sort of text we may want the computer to handle 
are: 
— a telephone directory 
- names and addresses 
- a timetable 
- expenses details 
Computers store all this textual information as strings. 
String manipulation by the computer would, for our first example, 
need to deal with: 
creating the telephone directory 
sorting the names and numbers into the correct order 
searching the directory for somebody's number 
revising the directory, i.e. updating or adding an entry 
printing out the directory in whole or part. 


K2: Quotes and Quote Image 


QUOTES 
All strings are enclosed in quotes ‘‘’’ when: 
(1) They are to be INPUT from the keyboard, as in a program 
line such as: 10 INPUT A$ . When the line is run the 
cursor оп the screen appears already enclosed in quotes |1 |”. 
You key in just the characters wanted in the string. 
(2) When used in programs with the PRINT instruction, e.g. 
20 PRINT ‘‘STRING’’. 
(3) When assigned in a program to a string variable, e.g. 30 
LET А$ = * STRING". 


THE QUOTE IMAGE KEY 
ON THE ZX81 


The QUOTE IMAGE is a special single character on the shift 
keyboard of the ZX81. 


6699 


It is used to write ordinary quotes in the middle of a string. 


eg.10 PRINT "SAY “BELLO” TOO] 


127 


When the line is run the double quotes will be printed on the screen as 
single quotes: 
SAY “HELLO” TOO 
A special character is needed as two single quotes won’t work. 
Key in and try to run each of the following lines: 

10 PRINT '' SAY “НЕТО”? ТОО” 

10. PRINT “БАУ”; "HELLO"; "TOO" 

10 PRINT “ SAY "HELLO" TOO" 
The Spectrum has no QUOTE IMAGE character. Instead, you must 
put two quotes for every one you want printed. For example, to obtain 
double quotation marks you type in PRINT“ °>, Single quotes 
are obtained with PRINT**** ’’’’. Program listings look the same for 
both machines. 


K3: String Input 


On running 10 INPUT A$ the letter cursor appears at the 
bottom of the screen with quotes round it, prompting you to 
key in characters for the string 


= [L] = 


On the Spectrum this can also be the C-cursor - ‘‘ me 


STOPPING STRING INPUT 


When keying in the characters for the string to be input notice 
that BREAK and STOP have no effect. 
To escape (1) Use the < key to get outside the quotes. 
(2) Press STOP, NEWLINE (ENTER) 
or 
press 
| 


There is a special form of string input, using the INKEYS instruction: 


INKEYS$ 


When INKEYS is encountered by the computer it reads the 
keyboard to determine if a key is being pressed. It does not 
wait for input like the INPUT instruction. If a key is being 
pressed it returns the string containing the mode 
character of the key being pressed. If no key is being pressed 
it returns the empty string ‘‘’’. 


128 


The Spectrum returns the mode character with INKEYS$ if in the 
CAPS mode. 

We can spend as long as we want before we input a string with the 
INPUT command, since the cursor will remain on screen. If we want 
to take advantage of the fact that, unlike INPUT, INKEYS does not 
require NEWLINE(ENTER) to be pressed, we must arrange a delay. 

Try this program: 

10 PRINT “PRESS A KEY WHEN READY” 

20 IF INKEY$-''"" THEN GOTO 20 (no spaces) 

30 LET AS-INKEYS$ 

40 PRINT “YOU PRESSED ”;А$ 
Line 20 sends the program back to the beginning of line 20 as long as 
no key has been pressed. Line 30 makes A$ the single character string 
returned by INKEY$ when a key is pressed. 

Due to a design error the Spectrum has far less predictable keyboard 
scanning using INKEYS than the ZX81. If you type in the program as 
above on the Spectrum it will work about half of the time. The rest of 
the time it will skip over line 30. This program will work every time 
though: 

10 PRINT “ PRESS A KEY WHEN READY" 


20 PAUSE 0 
30 PRINT “YOU PRESSED ”’;INKEY$ 


Experiment with the two versions to see this problem in action. The 
action of PAUSE 0 is to stop until a key is pressed. The first key 
pressed will be the INKEY$. PAUSE will be dealt with later, but 
remember this quirk of the Spectrum, and this method of dealing with 
it. The rule is to use PAUSE 0 immediately before INKEYS is used in 
a program line, to wait for input. 
Now enter and run this program: 
10 PRINT “PRESS 6” 
20 IF INKEY$ =“ 
THEN GOTO 20 (on the Spectrum 20 PAUSE 0) 
30 IF INKEY$ = “6” THEN GOTO 60 
40 PRINT “FOLLOW INSTRUCTIONS" 


50 GOTO 20 
60 PRINT “ENDING PROGRAM NOW" 
70 STOP 


Line 20 does the same as before, but line 30 now checks that the right 
key has been pressed. Notice the 6 must be enclosed in quotes, because 
INKEYS returns a string. If 6 was pressed, the program goes to line 60. 
If any other key was pressed, it goes to 40, prints the message, and then 
is sent back (line 50) to line 20, which waits for another key to be 
pressed. 

Games programs, which require interaction, often use INKEY$ in a 
loop, so that every time the program loops, it checks which key, if any, 
Is being pressed. 


129 


K4: Length of a String 


LEN 


The length of a specified string A$ is obtained by using the 
function: LEN A$. The length is given as the number of 
characters and is the current length of the string. 


Spaces are included in the length of a string. 
EXAMPLES 


1 10 LET A$=‘‘SINCLAIR”’ 
20 PRINT LEN A$ 
Check that the result is 8. 
2 10 LET AS= “А B’’ (9 spaces between A and B) 
20 PRINT A$ 
30 PRINT LEN A$ 
Key in and run. 
3 10 LET A$- “PRINT” 
20 PRINT A$ 
30 PRINT LEN A$ 


Key in the program first with PRINT formed from separate keys, and 
then change line 10 so that PRINT is formed by pressing the 
key. 
Why are the answers different? 
4 10 INPUT A$ 
20 PRINT A$, LEN A$ 
30 GOTO 10 


K5: Null Strings 


A string with no characters is called a null string. For 
example: 


LET A$ — 6699 
The length of the string is 0. 


A string which contains spaces is not a null string. A space is a character 
obtained by pressing [SPACE] . The null string is returned by 
INKEYS if no key is being pressed. 


Exercises 


1 Key in and run the following program: 


10 ТЕГА" 


130 


20 PRINT A$ 

30 PRINT LEN A$ 
2 Key in and run this program: 

іё LET A$e!' ” 

20 PRINT A$ 

30 PRINT LEN A$ 


К6: String and String Array Variables 


AS 


is a string variable used to store strings. It consists of a single 
letter (À to Z), followed by the dollar sign. 
Twenty-six variables of this type are thus possible. 


The Spectrum accepts upper and lower case letters, but treats, e.g. k$ 
as the same string as K$. 


AS(N) 


is a string array variable or string list variable where N refers to 
the number of strings in the list. String lists must be 
dimensioned as an array before the string array variable can 
be used, by the DIM (DIMension) instruction. 

Using the array notation, an unlimited number of string 
variables are possible. 


Again, the Spectrum accepts upper and lower case letters, but does not 


differentiate, e.g. b$(N) and B$(N) are the same. 


Caution: A$(N) can have two meanings in a program. 

(1) It can refer to the N’th character in a string A$. 

(2) It can refer to the N'th string in a list or array of strings. In this 
case the string array must previously have been dimensioned with a DIM A$(N) 
instruction. 


K7: String and String Array Dimension 


STRING DIMENSION 


DIM AS(N) 
sets a fixed length of N characters for the string. For example: 
10 DIM А$(6) 
sets a length of 6 characters for the string А8. 


131 


If strings of length <N (less than N characters) are assigned or input, 
then space characters are added to make up the complete string of 
length N. Spaces do not show up on the screen when they are printed! 
(To check they are in the string we can ask for their character set code 
to be printed using the CODE instruction. We'll get to this later.) 

If more characters than the number allowed in the DIM AS$(N) 
statement are assigned from INPUT or LET statements they are 
ignored. If strings are not dimensioned their length is effectively 
unlimited. 

The DIM statement fixes the length of a string until changed by 
another DIM statement. LEN is thus not useful when strings are 
dimensioned. 


STRING ARRAY DIMENSION 


The DIM statement for string arrays has the form: 
DIM A$ (N,L) 

where N = number of strings and L = the fixed length of each 
string. A may be any single letter A to Z, but must NOT be 
the same as a simple string variable. Each string is set to 
contain L spaces initially. 

For example, DIM A$(3,4) will reserve storage space for 3 
strings, A$(1), A$(2), A$(3), each of length 4, іп the string 
array A$. 


K8: String and String Array Assignment 


STRING ASSIGNMENT 


Strings are assigned to string variables using the LET or 
INPUT instructions. For example: 

LET A$ = “А STRING" 
or INPUT A$ 


This establishes a value for the string. 
As we shall see later, the value may be a literal value in quotation 
marks, or a string or substring value. 


STRING ARRAY ASSIGNMENT 


5 DIM А$(3,9) 
10 LET AS(1)- “SINCLAIR” 
20 LET А%(2)- ‘‘COMPUTING’’ 
30 LET А$(3) = *COURSE" 
assigns 3 strings to the string array variable А$(3). 


132 


We can also use an INPUT instruction: 
10 INPUT А%(1) 
20 INPUT A$(2) 
30 INPUT А$(3) 


Exercises 


1 Key in and run this program: 
10 DIM A$(2,9) 
20 LET A$(1)- “PERSONAL” 
30 LET A$(2) = 'COMPUTING " 
40 PRINT А$(1), A$(2) 
2 Now key in and run this. Input different strings of varying 
length. The string length is set at 8 in line 10. 
10 DIM AS$(3,8) 
20 INPUT AS(1) 
30 INPUT А$(2) 
40 INPUT А$(3) 
50 PRINT А%(1) 
60 PRINT А%(2) 
70 PRINT А$(3) 
3 Key in and run this program: 
10 DIM AS(6) 
20 INPUT A$ 
30 PRINT AS$ 
40 PRINT LEN A$ 
50 PRINT АФ “ЕМГ” 
60 GOTO 20 
line 10 sets a length of 6 characters for A$ 
line 20 asks you to input a string 
line 30 prints the string 
line 40 prints the size of the string in terms of characters 
line 50 prints END starting directly after the 6th character in 
the string 
line 60 loops us back to input another string 
a) INPUT less than 6 characters. 
See that the remaining characters are spaces. Notice that 
LEN A$ always gives 6 even though different numbers of 
characters are input for А8. 
b) INPUT 8 characters. 
Notice the extra characters are ignored. 


K9: Substrings and String Slices 


A SUBSTRING or a STRING SLICE is any set of consecutive 
characters taken in sequence from the parent string. For 


133 





example, for the string – “ABCDEFG'”: 


a substring 15 “СПЕЕ” 
or “АВС” 


or шм Ы 


А substring сап Бе а single character. 


SPECIFYING SUBSTRINGS 


AS(P TO Q) 


«ANYSTRING" (P TO Q) 


where P is the first character and Q the last character of the 
substring wanted іп the strings A$ or ‘‘ANYSTRING’’. 


SUBSTRING ASSIGNMENT 


Any substring is itself a string. We can assign a string to a substring: 


10 DIM А$(12) 

20 LET A$ (1 TO 4) = “JOHN” 
30 LET A$ (6 TO 10)- *SMITH" 
40 PRINT A$ 


This program assigns strings to substring variables. 


EXAMPLES 


1 
2 


3 


10 PRINT “SINGLAIR” (2 TO 5) prints INCL 

10 РКІМТ “SINCLAIR” ( ТО 3) prints SIN, since 1 15 
assumed if it 1s omitted at the start. 

10 PRINT “SINCLAIR” (3 TO ) prints NCLAIR (omitting 
the character after TO means the last character in the string 15 
assumed). 

10 PRINT ‘‘SINCLAIR” (3 TO 3) prints М. 

This is more conveniently written as 

10 PRINT “SINCLAIR”” (3) 

Or 

10 LET A$- ‘‘SINCLAIR”’ 

20 PRINT А$(3) 

which prints the 3rd character in A$, exactly as with a literal 
string. | 

10 PRINT “SINCLAIR” (1 ТО 0) prints 4” 

1.е. gives the null string (по characters). 

Here is a program that uses names and numbers in single 
strings: 


134 


10 LET А%-"МАМЕ AGE" 

20 LET BS="TOM 16" 

30 LET C$z"BILL 14% 

40 LET D$=" JANE 17" 

20 PFINT АТ 1567;AS$C1 TO 4); АТ 
1:14:8%(6 TO 8) 

£20 PRINT АТ 4.,&:E$C1 TO 4); AT 
4; 14:Е%с(6 TO 7) 

70 PRINT АТ 7s6*C$(1 TO 4); AT 
7%:14:С%(6 TO 7) 

SO FRINT АТ 1016; D$(1 TO 4); 
АТ 10:14:1%(6 TO 7) 


Notice how we spread the print out using substrings. 


K16: String Concatenation 


A$ + B$ 
Concatenation means chaining strings together. It is derived 
from the word catenary meaning a chain. What the computer 
does is to ‘add’ them together to form a new string. 


“СОМ” + “PU” + “TER” = “COMPUTER” 


10 LET A$ = “СОМ” 

90 LET B$ = “PU” 

30 LET C$ = “TER” 

40 LET T$ = A$ + B$ + C$ 
50 PRINT T$ 


Note that the + operator is used for string concatenation. 


We cannot subtract, multiply, divide strings or raise them to powers, 
because they are not numbers. Although the ‘adding’ of concatenation 
uses the same symbol it is not an arithmetic operation. 
Key in and run the example program given above. 
Add some DIM statements to the program: 
2 DIM А%(6) 
4 DIM В5(6) 
6 DIM C$(6) 
Run it. You will notice that although the strings are chained they are 
far apart. Why is this? 
Now try this program: 


10 INPUT А5 
20 INPUT BS 
30 PRINT А5,В5,А5%В65 


40 LET AS = А54В5 
50 PRINT А5 

60 LET А$=А$+А$ 
70 PRINT А5 


Notice іп line 40 уге have incremented the string Бу adding B$ оп to 
A$. This gives us a new A$ made up of the old A$ plus B$. The 
statement in line 60 is equivalent, in string terms, to having a line 
which for numeric variables says LET A= A+A. 


K11: Comparing Strings 


The conditional operators: 
= <> <= < >= > 
may be used between strings and string variables using the 
IF... THEN instructions. For example: 
IF A$ = “YES” THEN GOTO .... 
IF N$ = B$ THEN PRINT .... 
IF A$< = B$ THEN GOTO .... 


When the computer compares strings of characters it does so by 
comparing the codes of each of the characters in sequence. A string is 
found to be less than another if it comes first in alphabetic order. If the 
strings contain numbers we should remember that numeric codes are 
less than alphabetic (letter) codes. This affects comparisons. (See 
Section P for the character codes.) 

Strings are compared in order of characters from left to right. For 
example: 


“AS, ЗЫ” 
"AD S A 
“А”< “АА” 
a d.e d 
“АЗ S “А4” 
“б” "LE 
= A “4Д” 


Key їп and run the next program. Input the strings above plus others 
you want to try and it will print out their relative alphabetic orders. 


10 INPUT A$ 

20 INPUT BS 

30 IF А5<В5 THEN GOTO 70 
40 IF А5-В5 THEN GOTO 99 
50 PRINT А5;">";В5 


60 5ТОР 
70 PRINT A$;"«"; BS 
80 STOP 

90 PRINT A$;"-";B$ 
100 5ТОР 


136 


This gives us a method for putting names into alphabetic order, like in 
a telephone directory. We also have a method of searching it, since we 
can check whether any name in the list is equal to the desired name. 

We have already used string equality, but here’s another example of 
string comparison: 


10 PRINT "DO YOU UNDERSTAND STRINGS?" 
20 PRINT “ANSWER YES OR NO" 
30 INPUT А5 


40 IF AS = "YES" ТНЕМ GO ТО 70 

50 PRINT “THEN READ THE SECTION AGAIN!" 
60 STOP 

70 PRINT "YOU ARE A GENIUS!" 

88 STOP 


Key it in and run it. Do you understand? 

The above assumes the use of capital (upper case) letters only on the 
Spectrum. For lower case letters, these are all after upper case letters in 
the ordering of strings. So on the Spectrum: 

AA<Aa 
Z<a 
Z1<z1 
SMITH<Smith 
So any ordering of strings must take this into account. For this text we 
assume the use of capitals throughout. 


Exercises 


1 The “TELEPHONE” program sets up a telephone directory 
with names and telephone numbers. It will search through its 
lists to find the telephone number corresponding to a given 
name. Run and analyse the program to find out how it works. 


10 REM "TELEPHONE" 

20 REM **PROGRAM SETS UP A TEL 
EPHONE DIRECTORY AND USES IT** 

30 PRINT "HOW MANY NAMES DO YO 
U WISH TO ENTER INTO THE DIRECTO 
Ry?" 

40 INPUT N 

50 PRINT 

60 PRINT “INPUT ";N;" NAME (20 
LETTERS) AND NUMBER(8 FIGS) PAIR 
5" 

70 DIM А$ (М, 20) 

80 DIM BS(N,8) 

90 DIM DŠ (20) 

100 PRINT 


137 


110 PRINT 

120 PRINT "NAME";TAB (22); "МОМВ 
ER" 

130 PRINT 

140 FOR F-1 TO N 

150 INPUT А$Ѕ (Е) 

160 PRINT AS(F); 

170 INPUT BS(F) 

180 PRINT TAB (22);BS$(F) 

199 NEXT F 

200 PRINT 

210 PRINT 

220 PRINT "TO CLEAR THE SCREEN 
TO USE THE DIRECTORY PRESS CONT 
AND NEW LINE KEYS" 

230 STOP 

240 CLS 

250 PRINT 

260 PRINT "WHAT NAME?" 

270 INPUT D$ 

280 REM **NEXT PART OF THE PROG 
RAM SEARCHES FOR THE NAME** 

290 PRINT 

300 PRINT D$; 

310 FOR F=1 TO N 

320 IF AS(F)-DS$ THEN GOTO 370 

330 NEXT F 

340 PRINT 

350 PRINT "NAME NOT FOUND" 

360 GOTO 260 

370 PRINT TAB (22);BS(F) 

380 PRINT 

399 PRINT 

400 PRINT "ANOTHER МАМЕ? (Y/N)" 

410 INPUT QS$ 

420 IF Q$-"Y" THEN GOTO 249 

430 PRINT 

440 PRINT "TO KEEP YOUR DIRECTOR 
Y AFTER SAVING, USE ""GOTO 240"" 
WHEN RUNNING THE LOADED PROGRAM 
қ NOT ""RUN""," 

450 PRINT 

460 PRINT "BYE FOR NOW" 

470 STOP 


2 Modify “ТЕГЕРНОМЕ” to create your own directory with 
your friends’ names and addresses or birthdays or telephone 
numbers. 


a) Redesign the program 
b) Document it 


c) Key it in 
d) SAVE it 
e) Debug it 
D LLIST it 


g) SAVE the working version 
h) Put it in your personal tape library 
1) Enter details in your notebook 


138 


K12: Strings and Numbers 


In addition to the handling of strings as strings, there are instructions 
which enable us to convert strings to numbers, numbers to strings, and 
to usefully manipulate various numerical values of strings and their 
characters. We have already dealt with LEN. The other available 
string functions are dealt with here. The first two instructions cover the 
character set which is dealt with in Section P. 


CODE A$ 


When applied to a string A$ CODE returns the character set 
code number of the first character in a string. For example: 
10 LET X = CODE “MOTHER” 

On the ZX81 X becomes 50, the code for M (CODE “М”). 
When applied to a single character substring, it returns the 

code of the substring: 
e.g. 10 LET A$ = “CODE” 
20 PRINT CODE А$(3) 
prints 41, the CODE for D (CODE ‘‘D’’). 

The Spectrum uses a different code to the ZX81 (called 
ASCII, an international standard). Thus, CODE 
“MOTHER” is 77, and CODE А$(3) in the above is 68 
(= CODE ‘‘D’’). 


CODE A$ (M,N) 


When applied to a string array CODE returns the character 
code of the N’th character in the M’th string. For example: 

10 DIM A$(10,10) 

20 LET A$(1)- ‘‘SINCLAIR’’ 

30 LET А$(2) = “BASIC” 

40 PRINT CODE A$(2,3) 
will print 38 (CODE‘‘S’’) on the ZX81, whilst on the 
Spectrum the *S' in ASCII code is 83 (there is no significance 
in one being the reverse of the other!). 


CODE А$(2), applied to a string array as above, would return the 
CODE of the first character in A$(2), just as when applied to a literal 


string or string variable. 


139 


CHR$ 


When applied to a number М, CHR$ N gives the single 
character string in the computer’s character set whose code is 
the number N. 
For example, on the ZX81: 

CHR$ 49 15 “L” 

CHRS 12 is “£” 
whilst on the Spectrum CODE ‘‘L”’ is 76 and CODE *'£" is 
96, so CHR$ 76 gives “1.” on the Spectrum, and CHR$ 96 


gives **£^', 


We can treat these characters as elements in a string and make up a 
word by concatenation. Try this on the ZX81: 

10 LET A$=CHR$ 63 + CHR$ 61 + CHR$ 36 + CHR$ 29 

20 PRINT A$ 

or this on the Spectrum: 
10 LET A$=CHR$ 83 + CHR$ 80 + CHR$ 69 + CHR$ 67 
+CHR$ 84 + CHR$ 82+ CHR$ 85 + CHR$ 77 
20 PRINT A$ 


VAL A$ 


Applying VAL to a string containing only numeric characters 
and arithmetic or logic operators, returns the result of the 
arithmetic inside the string. 


For example: 
10 PRINT VAL ‘14+2+3”’ 
prints 6 


10 LET A$= 43” 
90 LET BS =**4” 
30 PRINT VAL (A$ + B$) 
prints 7 
All recognised arithmetic functions can be used: 
10 PRINT VALSSOR 16" 
(prints 4) 


10 PRINT VAL “ABS -29” 
(prints 29) 


An interesting use of VAL is where alphabetic and numeric 
information in a string can be treated as substrings. Arithmetic can 


140 


then be performed on the numeric substring. For example, try this 


program which gives 


the total ages of three people in a group. 


LET ñ$="SMITH 23" 
LET ES="JONES 24" 
LET C$z"WEZT 17" 


LET T= VAL A$ca TO 93+ VAL 
BELS TO 935 VAL СФЕ TO 99 

PRINT AS 

РЕІМТ E$ 

PEINT C$ 

PRINT з» “TOTAL AGE "FT; 

"^ YEARS“ 


STR$ 


STR$ (N) returns the value of (N), a numeric expression, as a 
string. For example: 


STR$ 3.4 gives “3.47 
STRS$ (3*31) gives “93” 
STR$ (SOR 4) gives ‘‘2”’ 


STR$ is the complementary or opposite function to VAL 


To see STR$ in operation, and the complementary functions of VAL 
and STR$, try this program: 


10 
20 


Exercises 


LET X23 

LET Ү=0. 5 

LET А%= ZTR$ (X/Y) 

FEINT A$, VAL AS 

(ЕТ BS=AG+ 5ТК% X 

PRINT E$, VAL ES/2 

LET t= VAL С STRE С VAL AS+ 
VAL ЕФ)? 

PRINT С 


1 Write a program which inputs a number of strings 
calculates the total number of characters in each, and the total 
number of characters in all the strings. 

2 Write a program which calculates the total price of items in a 
shopping list, after receiving and printing out the string inputs of 


each item and 


its cost. 


and 


3 Write a program which will print a calendar for any month of 
next year. Key in the month names and lengths as a string in the 


program. 


141 


SECTION L: LOOPS 


L1: Loops 


A loop is a block of instructions that the computer executes 
repeatedly until a terminating condition is met. 


The usefulness of loops can be seen by considering three forms of a 
program to print out the first one hundred positive integers. 


10 PRINT 1 
20 PRINT 2 
30 PRINT 3 


9 Ww $ 6 P» 
ce te @ S 


1000 PRINT 100 
This program, which does not use a loop, is 100 statements long. This 
next program uses a conditional jump loop which does the same thing and 
uses only five statements. 


10 LET C=90 

20 LET C-C-«1 

30 PRINT C 

40 IF C< 100 THEN GOTO 20 
90 STOP 


The third program uses a FOR - NEXT loop which is the commonest 
method of looping in BASIC, and the most economical in program 
lines. 


10 FOR F - 1 TO 100 


20 PRINT F 
30 NEXT F 
40 STOP 


All loops have four characteristics: 
1 Initialisation (start value of counter) 
2 BODY of loop 
3 Modification oí counter 
4 Exit condition. 


Loop structures may be properly formed in two ways: 

1 CONDITIONAL GOTO STATEMENT LOOPS 

2 БОҚ... NEXT LOOPS 
Loops are extremely useful. They allow repeated procedures to be 
performed, and the values of the counters, which are modified each 
time the program passes through the body of the loop, may also be used 
in calculations, if care is taken. 


142 


L2: Counters 


Here are two examples of the use of the conditional GOTO loop: 


19 LET C=0 

ZO LET Себа 

30 FRINT "COUNTING" 

40 IF C “= 10 THEN GOTO 20 


90 PRINT "FINISH" 


10 LET С=0 
20 LET CsC*1 
20 INFUT A 
40 FRINT А 


ФО IF Cz10 THEN GOTO 20 
60 PRINT “END OF NUMBERS" 


The variable C is used as a counter in these programs, adding 1 every 
time the program loops. 7f the value of C is less than the value set then 
the GOTO statement is executed and the program loops. If it is greater 
then control passes to the next program line. This enables us to control 
the number of times the program lines within the loop are executed. 

Our procedure for using counters in the example programs above is: 

1 Initialise the counter 

2 Increment the counter (add 1) 

3 Do the task 

4 Check the counter. If it has not reached the final value then go 

back to item 2. If it has then program exits from the loop. 


Note that we can perform the incrementation of the counter in a 
different place: 

1 Initialise 

2 Do the task 

3 Increment counter 

4 Check the counter. If less than specified value, GOTO 2. If 

more than specified value, program exits from the loop. 
We must be careful to set the conditions properly to achieve our desired 
result (the correct number of passes through the loop). Look at the first 
two simple programs above again. How many times will each of them 
pass through the body of the loop? Which is wrong if we wanted to loop 
exactly ten times? If you don’t see the answer, key them in and run 
them. 

The GOTO statement in the program below enables the program to 
loop continuously between lines 50 and 80. This would continue 
indefinitely so it is important to get out of the loop at the appropriate 
point. This is achieved by line 60 utilising the IF (condition) THEN 
GOTO (line-number) statement. Notice that the value of the counter 
(N) 1s used inside the loop: 


143 


„Ө REM "SIMPLEI" 

20 PRINT “SEVEN TIMES TABLE" 
ЗО PRINT “UP TQ TIMES 20" 

40 LET N=0 

20 LET N=N+1 

&O IF М>20 THEN GOTO 100 

70 PRINT N+ 7#N 

so GOTO 50 


100 REM **#ЕМП++# 


Notice that the counting procedure in this program is set up differently 
again. Line 50 increments the counter. Line 60 checks the counter 
value. In this case, the IF- THEN statement has the effect of 
transferring control out of the loop if the counter exceeds 20, with the 
GOTO 100 statement. 
The procedure in this case is: 
1 Initialise 
2 Increment 
3 Check counter. If greater than specified 
value, jump to program end. 
4 Body of loop 
5 Return to 2. 
Key in the program. Run it to check it loops exactly twenty times. 
Then EDIT line 60, to insert: 
75 IF N> 20 THEN GOTO 100 
and delete line 60. Now run it. It is surprisingly easy to miss the 
desired number of loops, if you are not careful with the structure of the 
loop, and the exit conditions. (Change N220 in line 75 to N> = 20 and 
the program will loop the correct number of times). 

Different procedures using counters give different program 
structures. Look at the flowcharts of different counter procedures. 
Remember that the conditional test can put to use the >, <, >=,<=, 
= operators, as appropriate. 


144 


COUNTER FLOWCHARTS 


Counter = 
Start 


Value 












Counter = 
Counter + 
Step 


of loop 


Exit Loop 


145 


Yes 


Counter 


= Ətart 
Value 





Body of Loop 


Counter 


= Counter 
+ Step 













Counter 
= Finish 
Value 







No 


Exercise 


Consider a simple program to work out the squares of the first 20 
integers. 


19 PRINT "NUMBER", "SQUARE" 
20 LET М-й 

30 LET N=N+1 

40 IF N»20 THEN GOTO 70 

50 PRINT N,N*N 

60 GOTO 30 

70 REM*END OF PROGRAM* 


146 


The GOTO statement in line 60 will cause the program to loop 
continuously between lines 30 and 60. 

This would continue indefinitely but line 40 is inserted so that the 
program jumps out of the loop when N>20. 

N is used as a counter. Line 20 initialises N and line 30 increments 
N by 1 each time the program goes round the loop. 

Write a program which calculates and prints the square and the cube 
power of even numbers between 10 and 30. The counter will need to be 
incremented by 2 each time the loop is executed by a GOTO 
statement. 

Write a program which loops 10 times (counter 1 to 10) but uses 
another counter to print the squares of the ten numbers 5.25, 5.0, 4.75 
са. 3.0. 


L3: For – Next Loops 


This is a more convenient way of having a program loop. The loop is 
set up with the FOR... TO ... STEP and NEXT instructions used in 
combination. The loop goes from the first value to the last value, 
counting by adding the defined STEP value every time it loops until 
the exit condition is met. 


FOR (variable) = (first value) TO (last value) STEP (step) 
FOR C = (N) TO (M) STEP (X) 

where C is the counter variable or control variable of the loop 
and (N), (M) and (X) are numeric expressions. 

C can be any single letter À to Z. It must not be the same as 
a single letter numeric variable. It is initialised at value (N). 
(N), (M) and (X) may take any values, positive or negative, as 
long as repeated additions of (X) to (N) will reach (M). If 
STEP is omitted, + 1 is assumed. NEXT C indicates last line 
of the loop. It adds (X) to C and loops back if the total is less 
than (M). The program loops back to the line after the line 
with the FOR - TO - STEP instruction. 


The FOR - NEXT loop has a fixed procedure, unlike loops formed 
with conditional GOTO instructions. 
We form a FOR - NEXT loop in a program like this: 
10 FOR F - 0 TO 100 STEP 2 


rue: Body of loop 


40 NEXT F 
The FOR statement initialises the loop. 
0 is the start value 
100 is the stop value 
F is the counter variable and is initialised as Q 
STEP 2 is the increment. 


147 





NEXT F is the last line of the loop and increments 

the counter F by the STEP value. 
We can also decrement the counter (decrease it). For example: 

10 FOR F=100 TO 0 STEP -2 
(where the decrement is 2) 
The loop will be exited in the first example when Е>100 and in the 
second when F«0. F will take values 0, 2, 4 .... 98, 100 in the first 
case, and 100, 98 .... 4, 2, 0 in the second. Any program lines in the 
body of the loop will be repeated each time the program loops. 
Try these simple examples: 


10 FOR F=2 TO 4 STEP 1.3 
20 PRINT F 
30 NEXT F 


10 FOR F=4 TO -1 STEP -1 
20 PRINT F 
30 NEXT F 


10 FOR F=-2 TO 4 STEP 2 

20 PRINT F 

30 NEXT F 

40 PRINT 

50 PRINT "F EQUALS ";F;" ON EXIT" 


Convince yourself that this doesn’t work: 

10 FOR F-2 TO 4 STEP - 1 

20 PRINT F 

39 NEXT F 
The next one is an interesting example of the inaccuracies in the 
computer’s arithmetic: 

10 FOR Е-1.2 TO -0.3 STEP - 0.2 

20 PRINT F 

30 NEXTF 
The only reason for using F as the control variable is that it is 
convenient: FOR F can be entered just by pressing the F key twice. 
You can use any letter, but it is good personal programming practice to 
use the same letters consistently, and not use these for single letter 
variables. ‘I’ is often used by programmers as a control variable (I for 
Integer) but can be confused in program listings. 

This next example uses N: 

10 FORN=1TO15STEP 1 

20 PRINT N,N*N 

30 NEXT N 
We can use the value of the control variable in calculation within the 
loop. Edit STEP 1, so that line 10 reads: 

107 FOR N= 1 TO 13 
and run it again. STEP may only be omitted for a STEP of + 1. 


148 


In the program, line 10 allows N to go from 1 to 15 with a step value 
of 1. That is to say, N takes the values, 1, 2, 3, 4, 5, 6, 6, 8, 9, 10, 11, 
12, 13, 14, 15 each time performing the calculations within the loop. 

The next program illustrates the use of different values for the step. 
The value can be positive or negative, integer or non-integer. In the 
case of decimal increments or decrements there is the possibility of 
rounding errors if the loop is executed many times — it is therefore 
advisable to use integer values for the step and divide by the 
appropriate power of ten, if the loop variable is to be used in 
calculations. If this were done in the program below, lines 130 and 140 


would read: 
130 FOR N^ 10 TO 56 STEP 7 


140 PRINT N/10; TAB 8; (N/10)**2; 


TAB 16; (N/10)**3 ( ^ on Spectrum) 
The program calculates squares and cubes for: 
a. a Seer, > 31 (line 20) 
129, 115, МӘ, „аже 60 (line 70) 
L, Leds X tone wwe жж 5.6 (line 130) 


Once again, Spectrum owners should remember that their machine 
uses the ‘up-arrow’ ( 4) rather than the ZX81’s stars (**) to represent 
‘to the power of’. 


5 REM "MULTILOOP" 

10 PRINT "NUMBER"; TAB 8; "SQ 
UARE"; TAB 16; "CUBE" 

20 FOR N-1 TO 31 STEP 3 

30 PRINT N; TAB 8; N**2; TAB 1 
6; N**3 

40 NEXT М 

45 PRINT "ТҮРЕ СОМТ KEY" 

50 STOP 

60 PRINT "NUMBER"; TAB 8; "SQU 
ARE"; TAB 16; "CUBE" 

70 FOR N=120 ТО 60 STEP -5 

80 PRINT N; TAB 8; N**2; TAB 1 
6; N**3 

90 NEXT М 

100 PRINT "ТҮРЕ СОМТ KEY" 

110 5ТОР 

120 PRINT "NUMBER"; TAB 8; "SQU 
ARE"; TAB 16; "CUBE" 

130 FOR N=1 ТО 5.6 STEP .7 

140 PRINT N; TAB 8; N**2; TAB 1 
6; N**3 

150 NEXT N 


In this next program the total is represented by T which is initialised 
equal to zero (line 10). Each time the program goes through the loop 
the INPUT number is added to T (line 40) so that when the loop (lines 
20 to 50) is exited T represents the sum of the ten numbers input. The 


149 


program evaluates the average by dividing the total by the number of 
numbers input. 


5 REM “АУЕКАСЕ” 


10 LET T=0 

20 FOR N=1 TO 10 
30 INPUT X 

40 LET T=T+xX 

50 NEXT N 


60 PRINT “AVERAGE =”; 7/10 

This program illustrates a loop used to print a table. In this case a 
heading is given (line 70) and this must be outside the loop as it is only 
required at the beginning. We require all names and ages to be 
tabulated so the print statement doing this (lines 140, 150) must be 
within the loop. Finally, we require the average age, which is to be 
printed underneath, and so the print statement (lines 170, 180) is 
inserted after the loop has been completed. 


10 REM "LOOPS3" 

20 PRINT "THIS PROGRAM PRINTS 
OUT THE NAME AND AGE OF A 
GROUP OF PEOPLE AND WORKS 
OUT THE AVERAGE AGE" 

30 PRINT 

40 PRINT "INPUT NUMBER IN GROU 


5Ø INPUT X 

60 LET T= 

70 LPRINT "NAME", "АСЕ" 

80 FOR N=1 TO X 

99 PRINT "INPUT NAME" 

100 INPUT N$ 

110 PRINT “INPUT AGE" 

120 INPUT A 

130 LET T=T+A 

140 PRINT N$,A 

150 LPRINT N$,A 

160 NEXT N 

170 PRINT "AVERAGE AGE-"; T/X;" 
YEARS" 

180 LPRINT "AVERAGE AGE"; T/X;" 
YEARS" 


The flowchart of a FOR - NEXT loop would be drawn like this, if we 
used the standard set of symbols as presented in the unit on 
programming: 


150 





BODY OF 
LOOP 


No 





Yes 


EXIT 


So for a program like the following: 
10 FOR F= 2Т0%5ТЕР.5 
20 PRINT F*F 
30 NEXT F 
40 PRINT “ЕМГ” 
the flowchart would be like this: 


151 





However, FOR - NEXT loops are used so frequently that this is a 
somewhat inefficient way of representing a loop of this type. ‘There is 
another symbol often used, although it is not a standard symbol, which 
condenses all the required information. This has the form: 


152 







OUT OF LOOP 


END LOOP 


TO BODY OF LOOP 


Our example program would be represented like this: 





L4: Loops of Variable Length 


The first value, final value and step of a loop may have any values 
(including variables which may be specified using INPUT). The first 
example shows a simple program which allows all conditions in the 
FOR statement to be specified using the INPUT statement. 


153 


REM "VARLOOP" 


PRINT "ТҮРЕ INITIAL VALUE" 

INPUT I 

PRINT "ТҮРЕ FINAL VALUE" 

INPUT F 

PRINT "ТҮРЕ STEP" 

INPUT S 

PRINT "X","X**244*X-3" [ ^ Spectrum] 
FOR N=I TO F STEP 5 

LET YsN**244*N-3 [ 4 Spectrum] 
PRINT N,Y 

NEXT N 


It is important in such calculations to avoid the case where 'division by 


zero' occurs. À simple 
shown below: 


example of how this may be done (line 40) is 


REM "DIVZER" 

PRINT "X","1/(X-3)" 
PRINT 

FOR N=-9 TO 15 STEP 3 


IF М-3-0 THEN GOTO 80 
LET Y-1/(N-3) 

PRINT N,Y 

GOTO 90 

PRINT N,"INFINITY" 
NEXT N 


The final program in this section illustrates another way of having a 
variable loop size. The operator may use this program for any number 


of numbers between 1 


and 100. A marker (in this case — 1) is set to 


indicate when the input is complete, allowing a Jump out of the loop 
(line 69). This is a ‘dummy value’ — a value not normally entered. 


(N.B. DO NOT JUMP INTO THE MIDDLE OF A LOOP i.e. a 


loop must always be entered from the FOR statement.) 


REM "STDDEV" 

LET T-0 

LET 5-й 

LET С-й 

PRINT "THIS PROGRAM WORKS O 
UT AVERAGE AND STANDARD DEV 
IATION OF A SET OF NUMBERS" 
PRINT 

PRINT "TYPE NUMBERS ONE AT 
A TIME,TO FINISH TYPE -1" 
FOR N-1 TO 100 

INPUT X 

IF X--1 THEN GOTO 140 

LET T=I+X [ ^ Spectrum] 
LET S=S+X**2 

LET С=С+1 

NEXT N 

PRINT 

PRINT "AVERAGE IS ";T/C 
PRINT "STANDARD DEVIATION I 
S ";SQR (S/C-(T/C) **2) [ 4 Spectrum] 


154 


The procedure used in this program can confuse the flow of a program 
and must be used with care. It is useful on occasion, but it is preferable 
to have only one entry and one exit from a loop. In this program, the 
loop may be exited from line 90 in addition to the normal termination, 


when №100. 
L5: Nested Loops 


We can place one loop inside another loop, so that every time the 
program goes through the outside loop, it will perform the inner loop 
sequence. The inner loop must be entirely within the outer loop. Loops 
are said to be NESTED one inside the other. Loops can be nested to 
any depth, i.e. we can have as many loops as we wish, as long as 
they’re correctly arranged. 


30 FOR A=1 TO 6 
40 FOR B=1 TO 3 


in hs ТТТ Inner Loop 


| Outer Loop 
80 NEXT B | 
120 NEXT A 


To have a third loop correctly placed, it would have to be inside the B 
(Inner) Loop, or outside the A (Outer) Loop. 
Be careful to avoid crossing the loops: 


10 FOR A=1 TO 6 
20 FOR B=1 TO 3 


80 NEXT B 


Programs with wrongly arranged loops will run, without giving an 
error message, but won't give you the correct answers! 

To illustrate the use of nested loops, here are two programs. The first 
evaluates and prints out the squares, cubes and fourth powers of the 
first ten integers. Each number (N = 1 TO 10) is to be raised to the 
appropriate power (E=1 TO 4). Note that the loops are correctly 
nested. 

20 FOR N=1 TO 10 


Ee FOR E- 1 TO 4 
50 NEXTE 





REM "NEST" 

PRINT "NUMBER";TAB 7; "SQUAR 

E";TAB 14; "CUBE";TAB 21;"4T 

H POWER" 

20 FOR N=1 TO 10 

30 FOR E-1 TO 4 

40 PRINT TAB (E-1)*7;N**E; [^ Spectrum] 
50 NEXT E 

60 PRINT 

70 NEXT N 


н 
Qu 


You will get a printout that starts off like this: 
NUMBER SQUARE CUBE 4TH POWER 


1 1 1 1 

2 4 8 16 
3 9 27 81 
4 16 64 256 


The flowchart for the ‘‘NEST1’’ program, using the flowchart symbol 
for FOR - NEXT loops we have introduced, will look like this: 


START 





We can see the sequence of operations by tracing the program. 


Line 20: 
Line 30: 
Line 40: 
Line 50: 
Line 60: 
Line 70: 





This table uses the ZX81 symbol for exponentiation. Notice how line 
40 uses the value of E to format the output. 

The second example assumes that a company employs three 
salesmen who keep sales figures for each week. At the end of four weeks 
the company requires a summary of sales to be printed. Each salesman 
S (1 TO 3) has weekly takings W (1 TO 4). Notice again that the loops 
are nested within each other. 


30 FOR S=1 TO 3 


gon 70 FOR W=1 ТО 4 
110 NEXT W 


130 NEXT S 
NAME  WEEKi WEEK? WEEK3 WEEK4 
JONES 12 16 19 13 
BROWN 23 26 29 21 
SMITH 31 4 6 39 


10 REM *NEZTED* 

20 LPRINT "NAME": ТАБ 6: "МЕЕК1 
TAB i2:;"WEEKZ": TAB 207 "WEEKS 
ТАЕ 27: "WEEK4" 

ЗО FOR 5-1 TO 3 

40 PRINT “INFUT SALESMANS NAME 


- - 
- - 
че ча 


>30 INFUT N$ 

EO ІРКІМТ N$; 

79 FOR W=1 TO 4 

SO PRINT "TYPE WEEK "М" SALE 


90 INPLIT X 
100 LPRINT TAB (7*W-1);X 
110 NEXT W 
120 LPRINT 
130 NEXT $ 


157 


Exercises 


Write programs using loops to perform the operations stated: 


1 


Calculate the reciprocals (1/N), logarithms (LN N) and cubes 
(L**3 ог L 4 3) of even numbers between 20 and 36 and print 
them out in a table. 

An object is dropped and the variation of distance s with time t is 
given by s=4.9t*. Print a table of the distances fallen for each 
second from 1 to 15 seconds. 

Evaluate and print the values of ЗХ? + 4X — 7 for values of X 
between 6 and 8 in steps of 0.25. 

Evaluate SIN X for values of X from 0? to 360? in intervals of 
10°. Remember you must convert from degrees to radians. 
Print out the results in two columns. 

Print a table of the discount at 5%, 10%, 15%, 20% on articles 
from £100 to £200 in steps of £10. 

Find the sum of all odd numbers between 39 and 75. 

Find the sum of the series 1,1,2,3,5,8,... (Fibonacci) to 20 
terms. (Each term is the sum of the previous two terms.) 

Find all numbers less than 50 which can be written as the sum of 
two squares. (e.g. 13 = 2° + 3°) 

A ball is dropped from a height of twenty metres and rebounds 
one-half the height on each bounce. What is the total distance it 
travels? Assume the ball stops bouncing on its hundredth 
bounce. 


158 


SECTION M: PLOTTING 


M1: Plot and Unplot 


The screen size is the same on both the ZX81 and the Spectrum. It is 
divided into 24 x 32 character cells in the same way for printing on the 
screen. The bottom two lines are reserved for use by the computer. 
However, the plot screens of the ZX81 and Spectrum differ. The 
principle is the same, that of dividing up the screen into small squares, 
each of which can be blacked in separately, but the Spectrum has a 
higher resolution plot screen than the ZX81. This means that the 
screen is divided up into smaller squares (called pixels, short for picture 
elements) on the Spectrum. The Spectrum has extra graphics 
commands not available on the ZX81 which make use of these pixels, 
some of which are mentioned in this Unit, but are dealt with fully in 
Section W. The commands are also different on the two machines, so 
we will describe the two separately before dealing with some of the uses 
of these commands. 

Spectrum users should note the principles of plotting as presented 
here (even where we note that a particular process is easier using one of 
the Spectrum graphics commands, since it is the principles that are 
important, and can be extended to more complex tasks), and not just 
feel superior to the ZX81 user, who has no access to CIRCLE or 
DRAW! 

On both machines each pixel is specified by X,Y co-ordinates. Thus, 
on the ZX81 (0,0) is the bottom left-hand corner and (63,43) is the top 
right-hand corner. There are 4 pixels in each character cell. 

PLOT X,Y - blacks out the picture element (pixel) with co- 

ordinates X,Y. 

UNPLOT X,Y - blanks out the pixel with co-ordinates X,Y. 

The PLOT co-ordinates run from 0 to 63 across the screen left 

to right (X co-ordinates) and from 0 to 43 up the screen 

bottom to top (Y co-ordinates). 

As a memory aid, remember that X is ‘a cross’, and X before Y. 

It is a simple matter to print horizontal and vertical lines. This 
program plots a horizontal line across the screen: 

19 FOR N = 0 TO 63 
20 PLOT N,20 
30 NEXT N 
See if you can write a program that plots a rectangle. 

Each of the character cells on the Spectrum’s screen has 8 x 8 = 64 
pixels, and there are thus 176 in any column up the screen and 256 in 
any line across the screen. Once again specifying each pixel with X and 
Y co-ordinates, 0,0 is the bottom left-hand corner and 255,175 is the 
top right-hand corner. 

Whilst PLOT X,Y on the Spectrum blacks in the pixel element in 


159 


exactly the same way as on the ZX81, there is no UNPLOT statement 
on the Spectrum. To erase the dot again the OVER 1 facility is used. 
Thus, to erase at X,Y you must enter a multiple statement line. 
OVER 1: PLOT X,Y - blanks out the pixel at co-ordinates X, Y 

Although it is perfectly possible to plot a horizontal line to the screen 
using a program similar to that used on the ZX81: 

10 FOR N=8 TO 255 

20 PLOT N,20 

30 NEXT N 
it is far simpler on the Spectrum to use the following type of 
formulation: 

10 PLOT 0,20: DRAW 255,0 

It is also possible to get some semblance of motion. ‘The program below 
moves a dot across the screen: 


On the 2Х81 On the Spectrum 
10 FOR N= 0 TO 63 10 FOR. N= 0 TO 255 
20 UNPLOT N - 2,20 20 PLOT OVER 1; N - 2,20 
30 PLOT N,20 30 PLOT N,20 
40 NEXT N 40 NEXT N 


It 1s possible to construct simple shapes using PLOT. Here is a ZX81 
routine to draw a (somewhat stylised) dog: 


10 LET X=0 

20 LET Y=10 

38 PLOT X,Y 

40 PLOT X+1,Y-1 
50 FOR N=2 TO 4 
68 PLOT X+2,Y-N 
70 NEXT N 

80 PLOT X+3,Y-2 
990 PLOT X+4,Y-2 
100 FOR N=1 TO 4 
110 PLOT X+5,Y-N 
120 NEXT N 

138 PLOT X*6,Y 
140 PLOT X+7,Y-1 


It can sometimes be worth remembering that the PLOT pixels are not 
exactly square. The visible variation from square will depend on the 
type of plotting being done, and the particular TV screen in use. It is 
worth drawing what should be a square on the screen, and simply 
measuring the variation with a ruler. Try running this program, and 
do this for different areas on the screen, so that you can check if the 
variation is constant. Note the double loop, which is often useful in 
PLOT routines. 


On the ZX81 On the Spectrum 
10 FORF-10 TO 30 10 FOR F=10TO 100 
20 FOR L= 10 TO 30 20 FOR L=10 TO 100 
30 PLOT F,L 30 PLOT F,L 
40 NEXT L 40 NEXT L 
50 NEXT F 50 NEXT F 


160 


The variation from square on the screen is typically in a ratio between 
1.1:1 and 1.2:1 (across screen/down screen). This means a ‘square’ 
that looks square will need to be 10 pixels across and either 11 or 12 
pixels down. 

Most PLOTting is done utilising loops. To PLOT a circle we need 
to choose a suitable STEP value for a loop that runs either from @ to 
360 (degrees), or 9 to 2 PI (Radians). We also have to set a centre to 
give us a circle where we want it, and a radius such that it will fit the 
screen. For a circle in degrees, code in this program: 


On the ZX61 On the Spectrum 
10 FORD=0TO360STEP10 10 FOR D=0 TO 360 STEP 2 
20 LET R=D*PI/180 20 LET R=D*PI/180 
30 LET X=30+20* COSR 30 LET X=120+80* COS R 
40 LET Y=20+20* SINR 40 LET Y=80+80* SINR 
50 PLOT AY 50 PLOT X,Y 
60 NEXT D 60 NEXT D 


Line 2@ converts to radians, in which all the trigonometric functions of 
the computer work. Line 30 calculates the horizontal component, and 
line 40 the vertical. The SIN and COS functions are multiplied by 20 
(80 оп the Spectrum) to give a radius of 20 pixels. The centre is set for 
the 7Х81 at pixel 30, 20, and for the Spectrum at pixel 120, 80. In 
most cases, it is convenient to consider the PLOT screen to be 60 x 40 
pixels (ZX81), rather than 64 x 44, in order to set scales and position 
plots оп the screen, and 240 x 160 similarly for the Spectrum. 

Having set the basic values, we can introduce variations within the 
loop into the above program. We can calculate the radius value and get 
a spiral plot. Alter the program to: 


For the ZX81 For the Spectrum 
10 FORD-20 ТО 360 STEP10 10 FORD-0 TO 360 STEP 2 
20 LET Z = D*PI/180 20 LET Z= D'PI/180 
30 LET R-Z*3 30 LET R-Z*10 
40 LET X = 30 + R*COS Z 4) LET X = 120 + R*COS Z 
5) LET Y=20+R*SIN Z 30 LET Y=80+R*SIN Z 
60 PLOT X,Y 68, PLOT Q<, Y 
70 NEXT D 70 NEXT D 


Calculating additional values, all within the loop, and using the loop 
values as a basis, provides complex shapes fairly easily. Alter the first 
three lines of the program: 


For the ZX81 For the Spectrum 
10 FOR D = 0 TO 360 STEP 5 10 FOR D-0 TO 360 
20 LET Z=D*PI/180 20 LET Z=D*PI/180 
30 LET R= 20*SIN(Z*4) 30 LET R =60*SIN(Z*4) 


RUN it. From a simple circle, we now have the basis for a polar graph 
plot and can identify a scale of values for PLOTting that will fit the 
screen. Similarly using parametric equations for the ellipse on the 


ZX81, X goes from 10 to 50 as COS goes from - 1 to 1 and Y from 10 


161 


to 30 as SIN goes from — 1 to 1 round the circle. Notice this uses 
radians directly (2*PI radians = 360 degrees). Spectrum plot points are 
multiplied by 4. 
For the ZX81 
10 FOR N-0 TO 2*PI STEP PI/20 
20 PLOT 30 + 20*COS N, 20 + 10* SIN N 
30 NEXT N 


For the Spectrum 
10 FOR N =0 TO 2*PI STEP PI/180 
20 PLOT 120 + 80 *COS N, 80 + 40*SIN N 
30 NEXT N 
Try altering the multiplication factors in line 20 for different ellipses. 
Alter the STEP value to get a continuous line. 

Of course, on the Spectrum a simple CIRCLE statement enables us 
to achieve the same result demonstrated in our first example much 
more quickly. For instance: 

CIRCLE 128,88,50 
will draw a circle of radius 50 pixels with its centre in the middle of the 
screen. This is included with the additional Spectrum functions in 
Section W. Note however that the calculated circles are more accurate 


than the ones drawn using CIRCLE, but a lot slower to PLOT! 
Exercises 


1 PLOT the extreme corner pixels, measure the rectangle and use 
the computer in command mode to calculate the proportions of a 
pixel rectangle on your screen. 

2 PLOT a circle, using radians directly, without a degree 
conversion, with another circle, half the radius, inside. 

3 PLOT a more accurate circle with allowance made for the pixels 
being non-square, by altering the multiplication factors for 
either COS or SIN. 

4 Change the spiral routine to produce a double spiral (i.e. going 
round the circle twice). 

5 Experiment with the rosette producing program. Alter the 
values of R in line 30 by changing the factor by which Z is 
multiplied. Try Z**2 (Z^42 on Spectrum) and similar 
expressions. 


M2: Graph Plotting 


Simple graphs may be plotted using the PRINT functions already 
encountered. The following program illustrates its use for drawing a 
histogram. Lines 20 to 70 allow twelve values to be input and make Z 
the largest value input. Lines 90 to 150 plot out the histogram allowing 
the maximum value (i.e. Z) to be 25 columns long and all the others are 
drawn in proportion. 


162 


10 REM "HISTO" 

20 DIM M(12) 

30 LET 2-0 

40 FOR N=1 TO 12 

50 INPUT M(N) 

60 IF M(N) > 2 THEN LET Z=M(N) 
70 NEXT N 

80 REM **PLOT** 

90 FOR N-1 TO 12 
100 PRINT N;TAB 4; 

110 FOR L-1 TO M(N) STEP 2/25 
120 PRINT "*"; 

130 NEXT L 

140 PRINT 
150 NEXT N 


Result: 


LKR KKK ke e e e ke e e ke e e e e e Х 
2 **k* 

d kk ke ke e ke e e e e e 
4 kkKKKKKEK 

5 ЖЖЖЖ Ж 
б á kkkkkkkkkkkkkkkkkkkkkkkk 
7 ж 

0 kkkKKKKKKKK 

О KkKKKKKK 

10 ****#****@**@**%*m*@**w**w** 

11 ****x* 

12 *********@**@*w* 


The STEP value in the program above is a SCALE FACTOR. The 
use of a suitable scale factor is needed in most graphical routines. Here 
is another version of a barchart program that identifies the scale factor 
and uses it to multiply the values to be plotted out using the asterisks. 
(The graphics characters can be put to use to draw solid bars, where 
the asterisk is used here.) 


10 REM *BARCHART* 
20 PRINT "ENTER MAX VALUE" 

30 INPUT M 

40 LET SCALE-25/M 

50 PRINT "ENTER VALUES (MAX 2 

0) ENTER -1 TO FINISH" 

60 PAUSE 150 

70 CLS 

80 FOR F-1 TO 20 

90 PRINT AT 21,0; "INPUT VALUE ";F 
100 INPUT V 

110 IF V--1 THEN Goro 190 
120 PRINT AT F,0; V 
130 PRINT AT F,5; 

140 LET V-V*SCALE 

150 FOR T-1 TO INT (V4.5) 

160 PRINT "*"; 

178 NEXT T 

180 NEXT F 

190 PRINT AT 21,0;" " 


163 


The identification of scale factors to produce the best plot possible 
within the avallable X,Y values on the screen is vital in all plotting 
routines. The plotted functions have to be plotted on the biggest scale 
that will enable them to fit the screen. This program fits the screen 
without any problem: 
ZX61 

10 FOR X =0 ТО 60 

20 PLOT X,SQRX 

30 NEXT X 
Spectrum owners should bear in mind that each pixel you can PLOT 
on the Spectrum is a quarter as wide and a quarter as high as those on 
the ZX81. Thus, as a general rule, you should allow for a factor of four 
when working with ZX81 scales, as shown in this discussion of scaling 
factors. In the program above, for example, the first line would read 
FOR X =0 TO 246. 

The program above does not give the best illustration of the shape of 
the curve, although it has the X,Y scales the same (one pixel = 1). 
Changing line 20 to: 

20 PLOT Х;2“5ОКХ 
gives a better graph. It is obvious, in this instance, that we could 
increase the scale factor — in this case the number by which we multiply 
SOR X to get the Y value —to 5, and the graph would still fit the 
screen. 

But if we try this program (do!): 

ZX61 Spectrum 
10 FOR X =0 TO 60 10 FOR X-0 TO 240 
20 PLOT X, X*X 20 PLOT X,X*X 
30 NEXT X 30 NEXT X 
we would only get a few points plotted before the computer stops with 
an ‘integer out of range’ error code. It is obvious that the maximum 
value in this case will be 60 x 60 = 3600 (7Х81) and 240 x 240 = 57600 


on the Spectrum. So if we used: 
20 PLOT X, X*X/100 20 PLOT X, X*X/400 


the highest value for the Y pixel would be 36 on the ZX81, which 
makes use of most of the screen. (For the Spectrum it would be 144.) In 
most cases, however, it 1s not so easy to see what the scale factors 
should be. We have a 44x64 screen to use on the ZX81 and а 
256 x 176 screen on the Spectrum, and so in general, for positive values 
only, suitable scale factors are given by: 


ZX81 Spectrum 
(X axis) 65 259 
Largest value of X Largest value of X 
(Y axis) 43 175 


Largest value for Y 


164 


Largest value for Y 


For a full range plot of a function that takes positive and negative 
values, for example SIN, we have to set a scale factor which refers to 
the screen available for use above and below the pixel Y value taken as 
zero. To give an example, for a SIN function, taking values between 
+1 and -1 we set the zero line as Y=20 (7Х81) or Y = 80 
(Spectrum). We then need to find a scale value such that the Y values 
vary between 20 above and 20 below this line (80 above and below for 
Spectrum) as SIN varies between + 1 and - 1. Again, it is obvious that 
we need to use a line like: 


2Х81 Spectrum 
20 PLOT X, 20 + 20*SIN X 20 PLOT X, 80 + 80*SIN X 


To get a single full range curve we need X to vary from 0 to 2PI 
radians, so we can use: 


10 FOR X -0 TO 2*PI STEP 2*PI/60 
20 PLOT X, 20 + 20 *SIN X [80 + 80 *SIN X on Spectrum] 
3 NEXT X 


for full screen use. (Remember 2PI radius = 360°.) 

Up to now, although you have been told about the co-ordinates of 
the PRINT and PLOT screens, we have treated the use of PRINT and 
PLOT as two separate areas. 

Since the PRINT and PLOT co-ordinate systems refer to the same 
screen, the two may also be used in concert, but care must be taken. 
Confusion is likely to arise between the numbering systems, not so 
much in the numbering across the screen, but in the Y plane, where 
pixels count 0-43 (@-175 оп the Spectrum) upwards, and the print lines 
0-21 downwards. Pixels are coded X,Y, across and up, print positions 
L,C, down and across. The screen grids for printing and plotting are 
reproduced here for both the ZX81 and Spectrum. 


165 


THE ZX81 PRINT AND 


PLOT SCREEN 


You cannot PRINT or PLOT 


on the bottom two lines. 


«—— Lines 


An example: this is 


Columns —— the pixel (57,32) 


8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 


x 48 | 50 | 52 





Pixel x-coordinates PHT 


Pixel y-coordinates ----ь 


166 


An example: this is 


the pixel чыш 


| 
= 
E 
= 
О 
Q 


ESI 


q — s3}2uIp1009 Á |axid 


6/1. ¿9L 861 161 ЕРІ SEL 721 GLL Lit EOL 96 ZB 62 14 БӨ SS Zh ФЕ IE EE Gt и 
891 091 ZSL vti 961 821 001 Zit VOL 96 88 08 22 v9 95 BH OF ZE vC 9 8 


0 
38 
еу ~ 
<+ š 





бәш| OM} uuolloq eu) uo | 


1014 10 LNIHd Aijeuuou 1ouueo под 


N33439S 10 ld 
'? Іміна WNYLOAdS JHL 





Pixel x coordinates ——— р> 


It is useful, when both PRINTing and PLOTting on the screen, to 
work with one screen grid first, and then add the other grid. As an 
example, consider graph titles. We could, to get a title for a printout of 
a graph, use a direct command: PRINT ‘‘GRAPH OF 
Y = X**2/100’’, then use COPY, BREAK the COPY routine after the 
first lines printed, then PLOT the graph with our program and COPY 
that, but it’s not very elegant. We want the title on the screen with the 
plotted graph. We can first set the PLOT routine, for example: 


ZX61 Spectrum 
10 FOR N=0 TO 60 10 FOR N-0 TO 250 
20 PLOT N, N*N/100 20 PLOT N, N*N/400 
30 NEXT N 30 NEXT N 


By inspection, after RUNning the routine, we can add a title where it 
will not interfere with the PLOT. 


40, PRINT AT 0, 35: “27 
50 PRINT AT 1,0; “Y =X 7100 


This gives us a screen with everything on it, with the bonus of using 
standard notation for X°, not the BASIC’s ** (fon Spectrum) 
notation. A different function might require the PRINTed strings to be 
placed elsewhere. 


Exercise 


Write a program that will calculate the pixel co-ordinates of any 
PRINT square (character cell). Input L and C (for Line and Column), 
with suitable prompts erased by an empty string, and output 
“Piel” s Х; 4)”; Ү; 16 top right’’, etc. For the ZX81, output the four 
pixels in any specified character cell. For the Spectrum, output the 
X,Y co-ordinates of the four corner pixels. 


168 


SECTION N: SUBROUTINES 


N1: Subroutines 


A subroutine im BASIC is a program module performing an allotted 
task and is entered using a GOSUB statement. The section of program 
Is completed and exited by a RETURN statement which sends the 
computer back to the line following the GOSUB statement. A 
subroutine must only be entered via a GOSUB statement and exited by 
a RETURN statement. 
Two instructions are used to create subroutines. 
GOSUB (line number) - transfers control to the specified line 
number 
RETURN —leaves subroutine and returns 
control to the line immediately after 
the GOSUB instruction which 
transferred control to the subroutine. 


Spectrum users have probably noted that their machine prints GO 
SUB with a space. 


Here is an example of the program structure for these instructions: 


IBS ,.. 
110 GOSUB 500 --------(1) 
Таб ... 
TO uw 
140 GOTO 600 
520 REM *SUBROUTINE* 
(3) 5318 vs 


520 ... dy (4) 
539 wns 
540 RETURN 


600 STOP 


(1)  GOSUB - goes immediately to line indicated (500) 

(2) Continues program (lines 500-540) until RETURN reached 

(3) Program returns to line 120 (line immediately after GOSUB 
statement). 

(4) Itis vital to ensure that a subroutine is not entered accidentally 
when writing the program. Note that line 140 does this by using 
a GOTO statement to bypass the subroutine. Line 600 may 
continue the program, or be a statement such as REM*END 
OF PROGRAM”. It is a useful practice to end a program at the 
highest line number, which indicates successful completion of 
the whole program. The alternative, stopping the program with 
a line 140 STOP, could also be used. 


169 





Subroutines are often used for repeated procedures and may be 
thought of as separate program structures: 








MAIN ROUTINE SUBROUTINE 
100 
114 GOSUB 500—~>|500 REM SUBROUTINE * 
120 -&——— 510 
130 520 
14) GOSUB 500— 1530 REM * END OF SUBROUTINE * 
150 =< 540 RETURN 
160 


The computer stores the line number of the GOSUB instruction 
(whereas it doesn’t with a GOTO). The RETURN instruction 
transfers control back to the line number after the /atest GOSUB. As 
shown above, this means we can enter a subroutine repeatedly in the 
course of a program. 


N2: Subroutine Example 

The example program given below evaluates the circumference and 
area of a circle, and has a subroutine to round the results to two 
decimal places. The program works as follows: 


(1) Calculates the circumference (line 40), and makes this figure 
equal to variable Z (line 45), which is the variable the subroutine 
will round. 

(п) Enters subroutine (line 50). 

(ш) Corrects answer to 2 significant figures (subroutine lines 
200 — 230), and returns with rounded value of Z to line 60, 
which: 


(iv) Prints out circumference (line 60). 


The same procedure is then repeated for the area, the subroutine being 
entered (called) again in line 90. Lines 200 to 23@ of the program are 
then executed again, but the RETURN statement this time returns 
control to line 100 (the next line after the last GOSUB statement). 


It is essential to have line 110, which prevents the subroutine being 
entered accidentally when the calculation is complete. 


10 REM "CIRCLE" 

20 PRINT "TYPE RADIUS" 

30 INPUT R 

40 LET C=2*PI*R 

45 LET Z=C 

50 GOSUB 200 

60 PRINT "CIRCUMFERENCE IS ";2 

70 LET A=PI*R**2 [ ^ Spectrum] 
80 LET Z=A 

90 GOSUB 200 


170 


100 PRINT "AREA IS ";Z 

110 GOTO 3609 

120 REM *MUST NOT ENTER A SUBROUTINE 
EXCEPT BY A GOSUB* 

200 REM **SUBROUTINE TO CORRECT TO 
TWO DECIMAL PLACES** 

210 LET Z=INT (100*(Z4.005)) 

220 LET Z=Z/100 

230 RETURN 

240 **END OF SUBROUTINE** 

300 REM **END OF PROGRAM** 


The second example is a program to evaluate the sum of the series 
1 4 1/2! +1/3! +.. 41/10! to 6 decimal places. (The exclamation 
mark (!) means ‘factorial’. Factorial 5 (5!) is 5x 4x 3x2x 1, etc.). 

In this program there are two separate subroutines. The subroutines 
are both entered repeatedly. The first is to evaluate the factorial and 
the second corrects the answer to 6 decimal places. Although it is not 
essential to use subroutines in such a program it does improve the 
structure and make it considerably easier to follow the sequence of 
operations. 


19 REM "FACTORS" 

40 LET 5-й 

50 FOR 2-1 TO 10 

60 GOSUB 200 

70 LET T=1/X 

99 LET S=S+T 
100 PRINT Z;" TH TERM IS ";T 
118 NEXT Z 

120 GOSUB 300 
130 PRINT 

140 PRINT "SUM OF SERIES ";V 
150 GOTO 400 

200 REM **SUBROUTINE FACTORIAL** 
210 LET X=1 
220 FOR N=1 'TO Z 

230 LET X=X*N 
240 NEXT N 
250 RETURN 

300 REM **SUBROUTINE 6 D.P. ** 
310 LET V=INT (1E6*(S+5E-7) ) 
320 LET V-V*1E-6 

338 RETURN 
400 REM **END** 


Results on screen: 


TH TERM IS 1 

ҮН TERM IS 0.5 

TH TERM IS @.16666667 
TH TERM IS .041666666 
TH TERM IS .083333333 
; - 0013888889 
TH TERM IS .0001964127 
TH TERM IS .000024801587 
TH TERM IS 2. 7557319Е-6 
TH TERM IS 2.7557319E-7 
SUM OF SERIES 1.7182862 


= оо - OY Ut i» Q N = 
< 
= 
"3 
г 
= 
= 
ні 
о 


- 


171 


Trace the program through for the first two terms to ensure that you 
can follow the flow. 


N3: Nested Subroutines 


This technique is similar to nested loops in that a subroutine is entered 
from another subroutine. 

In the simple example given the program enters the first subroutine 
(line 300) and from within this calls up the second subroutine (line 320 
calls up subroutine at line 400) which is completed and returns (line 
420) to the first subroutine which is then completed. See the diagram 
below of the program flow. 

Hand trace this program to discover the result of running it. (N.B. 
This program is only used to illustrate nested subroutines and the 
calculation carried out clearly can be done more easily without their 
use. ) 


10 REM “SUBROUTINE1" 
20 LET M=5 
30 GOSUB 300 
40 PRINT M 
58 GOTO 569 
300 REM ****1ST SUBROUTINE**** 
310 LET М=М+1 
320 GOSUB 400 
330 REM **RETURN TO MAIN PROGRAM** 
340 RETURN 
350 REM * k k k oo k k # k k k k k k k k k k k k Kk 
400 REM ****2ND SUBROUTINE**** 
410 LET M=M* (M+1) **2 [ # Spectrum] 
‘20 RETURN 
430 REM k k k k k k k k k k k k k k k k k k k k k k k 


500 PRINT "END OF PROGRAM" 


The diagram illustrates the procedure in the above program for two 


nested subroutines. 
30 GOSUB 300 
40 
50 сото 500 
(7) 360 
33$ sans 


320 GOSUB 400 


oo peas 


34@ RETURN 


Е" 
(3) 
35D .... 
(5) 49D .... 
410 .... 
420 RETURN 


430 owes 


(1) Subroutine 1 is called at line 30. 
Enter first subroutine at line 300. 

(2) Start executing first subroutine. 

(3) Subroutine 2 is called at line 320. 
Enter second subroutine at line 400. 

(4) Execute second subroutine. 

(5) RETURN at line 420 returns program to line 330 (line 
following GOSUB call). 

(6) Continue execution of first subroutine. 

(7) | RETURN at line 340 returns program to line 40 (line following 
GOSUB call). 

(8) Statement to avoid entering subroutines accidentally. 

The second example is typical of a computer games program. The 

nested subroutine ensures that the computer’s move is printed out each 

time before the player makes his move. 


10 REM "NESTSUB" 

20 REM **PART OF GAMES PROG** 
30 LET х-3 

40 GOSUB 600 

45 PRINT 

50 PRINT "YOUR MOVE WAS ";M 
60 PRINT "COMPUTERS MOVE ";X 
70 STOP 

600 REM **SUBROUTINE PLAYER** 
610 GOSUB 700 

620 PRINT "YOUR MOVE?" 

630 INPUT M 

640 RETURN 

700 REM **SUBROUTINE COMPUTER** 
710 PRINT "COMPUTERS MOVE ";X 
720 RETURN 


Note that it would make no difference if the nested (called from a 
subroutine) subroutine were to start at a lower line number than the 
subroutine which called it. Subroutines are always discrete program 
modules, wherever they are located in a program. 


N4: Recursive Subroutines 


A recursive subroutine is a subroutine that calls itself. This facility 1s 
not available in some versions of BASIC used on other computers. For 
some purposes this can be a very useful program structure. From 
within a subroutine, a GOSUB instruction is used to transfer control so 
that the program re-enters the subroutine. The computer stores each 
GOSUB call, with the line number to RETURN to, just as if the 
GOSUB call had been made to a different subroutine. The RETURN 
instructions are executed in reverse sequence to the order in which the 
GOSUB instructions were encountered. 

The example program below evaluates the factorial. of any number 
N, input as an integer less than 30. First the program, then the 
explanation: 


173 


20 КЕМ 
20 PRINT 
30 INPUT М 


"RECSUE" 
"TYPE NUMBER<20" 


40 IF М>20 THEN GOTO 200 


S50 БОЦЕ 100 
80 PRINT F 


20 КЕМ 


20 REM жЕ € € 93€ зен 3€ 9€ ж 


1 THEN GOTO 140 


100 REM *#+##SUBROLUT INE ++ 
110 IF N <> 

120 LET F=1 

iso GOTO 180 

140 LET NzN-1 

150 GOZE 100 

160 LET F=F*(N+1) 
170 LET N=N+1 

120 RETURN 

135 REM **##*# END SUE жж 
190 КЕМ 

200 РЕІМТ 


“OBEY INSTRUCTIONS, РЕ 


ESS RUN AND NEWLINE/ENTER" 


210 КЕМ **END#* 


To help us decipher the program flow, we can insert PRINT 
statements and add a counter, in order to code the GOSUB and 
RETURN instructions with a number to indicate the sequence in 
which the recursive calls are performed. Add the following lines to the 


program: 
5 LET C=90 
35 PRINT N 


45 LET C=C+1 


55 PRINT “RETURN TO MAIN 
РКОСКАМ” 


145 LET C=C+1 


146 PRINT “GOSUB CALL ”;С 


147 PRINT “N=";N 
155 PRINT''RETURN CALL “G 
156 LET C=C-1 


165 
175 


PRINT “Е=”;Е 
PRINT “N =’’:N 


(sets counter to count 
GOSUPB calls) 

(prints first value of N) 

(first GOSUB call from main 


program) 


(final RETURN executed) 
(increments counter each 
time GOSUB is used 
recursively) 

(prints each time GOSUB is 
used recursively) 

(value of N before each 
recursive GOSUB call) 
(prints each RETURN call as 
made, corresponding to the 
GOSUPB call of the same 
number) 

(decrements counter as each 
RETURN is executed) 
(value of F at each stage) 
(value of N at each stage) 


Then run the program for N = 3. The resulting ‘machine trace’ screen 


display 1s: 
174 


3 

GOSUB CALL 2 
N=2 

GOSUB CALL 3 
N=1 

RETURN CALL 3 
F=2 

N=2 

RETURN CALL 2 
F=6 

N23 

RETURN TO MAIN PROGRAM 
6 


If we draw up a trace using the data from this display (as below), we 
will see that the GOSUB at line 150 is executed for each value of N from 
1 to N. The RETURN calls are then made for each value from 1 to N, 
calculating F each time (line 160) and incrementing N (line 170), so 
that the value of factorial N is calculated as 1x2x3...x N. The 
flowchart of this program is quite simple, but the algorithm is not clear 
unless the sequence of GOSUB and RETURN calls is understood. 

The computer stores each GOSUB call in sequence in a portion of 
memory called the GOSUB stack, and each RETURN instruction 
removes one of these stored GOSUBSs, passing control to the line after 
the GOSUB call. Confusion is possible with recursive subroutines 
because the RETURNS are made to the same program line each time 
(line 160 in this case). 


“RECSUB”’ - Trace јот N = 3: 


50 GOSUB(1) 
60 

100 N-3 N=? N=1 
110 F 


120 
130 
140 Nš2 Nš! 
150 GOSUB(2) GOSUB(3) 
160 

E 


170 
180 R 


F = 1*9 F v 2%3 
N=2 N =3 
TURN(3) RETURN(2) RETURN(1) - (To main program) 


175 


Flowchart - ‘‘RECSUB”’ 





START 


©) (2) 


F=F*(N+1) 


RETURNS TO LINE 
RETURN AFTER LAST GOSUB 
CALL. 


В) 


176 


Notice that line 130 passes control to the RETURN statement of line 
180. Check for yourself that line 130 could be a RETURN instruction 
and the program would still run correctly. This is likely to result in a 
less visible flow in the program, however. 

The next program has a subroutine (starting at line 100) which calls 
itself in line 150. As for the previous program, insert suitable PRINT 
statements to print out the values of the variables and the number of 
GOSUB calls made. Hand trace the program for suitable integers, e.g. 
15 and 25. The program evaluates the highest common factor of the 
two numbers input. Note that in this case there are no processing 
statements between the GOSUB call in line 150 and the RETURN 
instruction of line 160. The sequence of RETURNS will be executed 
by control going repeatedly to line 16@ (the line after the GOSUB call), 
which does the next RETURN, until the last stored GOSUB is 
encountered, which will pass control back to line 5@ of the main 
program. 


5 REM “HCF" 

10 PRINT “TYPE ‘TWO POSITIVE INTEGERS" 
20 INPUT M 

30 INPUT N 

49 GOSUB 100 

50 PRINT "ANSWER IS";P 
68 GOTO 220 
100 REM **SUBROUTINE** 
110 LET P=N 
120 LET N-M-N*INT (м/м) 
130 LET M=P 
140 IF М-й THEN GOTO 160 
158 GOSUB 100 


210 REM 
220 REM **gND** 


N5: Computed Gosubs 


The line number N in a GOSUB N program instruction may be a 
computed expression: it is permissible to have any expression as the 
numeric value for a line number. 

We can make use of this in programs where we want to give the user 
some options of operations. Since we would write the program with 
these options as subroutines, a suitable choice of line numbers can 
allow us to present a menu to the user. Here are two (useless) examples 
to illustrate the principle: 


1) 10 PRINT "MAIN PROGRAM" 
20 PRINT "INPUT 1 OR 2" 
30 INPUT X 


40 GOSUB Х%100 

50 PRINT "MAIN PROGRAM ENDS" 
69 PRINT "NOW BACK TO MENU" 
70 PRINT 

80 GOTO 10 


177 


100 PRINT "FIRST SUBROUTINE" 
110 RETURN 
200 PRINT “SECOND SUBROUTINE" 
210 RETURN 
2) 10 REM *NESTED SUBS FOR MENU** 
20 REM **INITIALISE MENU GOSUB** 
30 LET MENU-14009 
40 REM **MAIN PROGRAM** 
50 PRINT "MAIN PROGRAM" 
60 REM .... 
70 PRINT "NOW TO MENU" 
80 PRINT 
90 GOSUB MENU 
100 PRINT "MORE MAIN PROGRAM" 
118 PRINT "MENU OR END PROGRAM?" 
120 PRINT "INPUT M OR E" 
130 INPUT NŠ 
140 IF N$-2"M" THEN GOSUB MENU 
150 GOTO 9999 
1000 PRINT TAB 3;"MENU" 
1010 PRINT ,,"1. OPTION 1",,"2. 
OPTION 2" 
1020 PRINT "INPUT 1 OR 2" 
1030 INPUT M 
1040 GOSUB (M*1000)+100Q 
1050 RETURN 
1100 REM ****SUB l*****x* 
1110 ВЕМ k k k k k k k k k k k k k * k 
1120 PRINT "SUB 1 COMPLETED" 
1130 PRINT 
1140 RETURN 
2100 REM ****SUB 2****** 
2110 REM £ k k k k k k k k k k k k k k 
2120 PRINT "SUB 2 COMPLETED" 
2130 PRINT 
2140 RETURN 
9999 STOP 


Notice the use of a variable ("MENU") to hold the line number 
(1000) of the Menu subroutine (Lines 20 and 30). This technique can 
be useful as a mnemonic in longer programs, and can help the user 
identify which program module has been called. 

This technique can be combined with the use of INKEY$ to give an 
instantaneous jump to the required subroutine. The program waits for 
a key to be pressed and then jumps to the required subroutine. 


10 PRINT "PRESS 1 FOR SUB 1"," 
PRESS 2 FOR SUB 2" 
20 IF INKEYS="" 

30 LET AS=INKEYS 


THEN GOTO 20 


35 IF А5-"1" OR А5-"2" THEN СО 
TO 60 

40 PRINT "KEYS 1 OR 2 ONLY PLE 
ASE" 

50 GOTO 10 

60 GOSUB VAL А5%100 

70 PRINT "BACK TO MENU" 

80 GOTO 18 


178 


PRINT "********k*kkkkkk" 


PRINT "SUBROUTINE ONE" 
PRINT "*********X**x" 


RETURN 

PRINT "soo x de e e e e x n 
PRINT "SUBROUTINE TWO" 
PRINT "s***k*kkkxkkx" 


RETURN 


Spectrum users should replace line 20 with 


20 PAUSE Q 


N6: Subroutine Use: Example 


As an example of the use of subroutines, here is a guess-the-number 
game. The program has three subroutines, one to get the number (lines 
150 — 190), one to check the guess (lines 210 — 300), and one for the 
success message (lines 350 — 410), which sets the marker MARK to tell 
the main program, which is the loop between lines 50 and 140, 
whether the number N (computer's number) is the same as G (the 
player's guess). This defines whether the success subroutine has been 


called as a result of the conditional test in line 110. 


22 
10 
20 


30 


REM "GUESSNUM" 

LET MARK =0 

LET TRIES=0 

PRINT “GUESS MY NUMBER, "++, 


“NUMBER: IS BETWEEN 1 AND 99" 


(M9 е „ ts 
cC uy < ord 
-— — ЫҢ М. !. 


Же 


_ 
— 


“ІЛ 


-- ұл pe bh FS p 

I 63 3 Кә ка 0 CY oo 
ез» 
йу, 


— 
1 
— 


i+ p» pee de dex 
ooo C on 
oO ch <s C) 


! 
о 


) LE" TR 


КЕМ жж СЕТ NUMBES жж 


ces LIE 


FO 
ES=TRIE'S+1 
PRINT ss “ENTER YOUR GUESS" 
INFLT 
Ж 


oe” Ramee ane 


ӘЕМ жж GOSIP CHEE ж 


DOSJE ооо 


REM жж GOSUB SuUmTE Ss жж 
IF DIFFzO THEN SOSE 280 
REM x CHECK MARK жж 

IF MARK=! THEN GOTO Soo 
БЕМ x LOOP BACK жж 
GOTO So 


ES cA каға 


REM XX%3 3333333333 3333 XE CE 
REM ** БЕТ NUMBER SUE: жж 
MEM 333 3 3 09 Ж € 0€ 303€ 9€ EHH 
LET N= INT С REND sv9541 
RETURN 


REM жж ENDS UE: xx 
REM X3 OX X АХ ЖАЖА EE 
REM 

БЕМ 3636363 ЖЖ Жы HEH 
REM жж HECK SUE xXx 
REM 33 33 09€ 3 0€ ЖҰ EE EH 


230 LET DIFF= ABS (G-N) 


IF DIFF250 THEN PRINT 9a "FR 


EEZING" 


179 


250 IF DIFF>25 AND DISF <= 50 T 
HEN PRINT 95 "COLD" 

260 IF DIFF>10 AND DIFF <= 25 T 
HEN PRINT у» "xWARIME" | 

270 IF DIFF>4 AND DIFF <= 10 TH 
EN PRINT +," ж НОТ жж " 

280 IF DIFE>O AND DIFF <= 4 THE 
N PRINT ss" жж #BCILING# жы" 
290 RETURN 


700 REM жж END CHECESZLUE xx 

210 REM ххх хз ЖЖЖ ЖЕК 

220 REM 

240 REM 33 CC 30 KHER HEHE HEH 

GEO БЕМ жж зи Sup ++ 

SEQ REM хажы ғ HH ED 

370 PRINT AT 9.95; "%%%%%7%%%7%%"; 
TAB 5: "$ SUCCESS %": TAB Si "$5 
HEEE ESE" 

380 PRINT АТ 10%5: "ІТ TOOK “ITR 
IES?" TRIES. “ 

390 LET MARK =1 

400 RETJEN 


410 REM жж END SUMCESS Sie жж 
420 REN X3X33X3 939 0 HE EK EE Y 
430 СЕМ 

470 REM жж ЖЖЖ 
490 REM жж END/RESUN MOD xx 
495 БЕМ 3*3 9 X 3 X 3 30 Ж Жы 
200 PRINT ,$4"ANUTHE SO? INPUT 
Y OR N" 

SiO INFUT A$ 
CL 
930 IF A$z"Y" THEN GOTO АО 

940 PRINT +. "Ok. BYE" 


wool STOP 


Se REM xx xx END хх жж 


The structure of the program is thus: 


Module 1: 
1. Initialise success marker MARK and variable to store number 
of guesses made (TRIES) 


2. Print Instructions 


3. Call GET NUMBER Subroutine 


Module 2 (Main program loop): 

1. Increment TRIES 

2. Input guess 

3. Call CHECK Subroutine 

4. Check if Guess equals Number. If it is, then call SUCCESS 
Subroutine 

5. Check marker. If Success subroutine has been called 
(MARK = 1), then GOTO END/RERUN module 

6. Loop back to Input guess again (1) 


180 


Module 3 (GET NUMBER Subroutine): 
1. Define random number 1-99 as number N 
2. Return 


Module 4 (CHECK Subroutine): 
1. Set variable DIFF equal to ABS difference of guess and number 
2. Check value of DIFF, print appropriate message 
3. Return 


Module 5 (SUCCESS Subroutine): 
1. Print success message, number of guesses made 
2. Set MARK equal to 1 
3. Return 


Module 6 (END/RERUN module): 
1. Print prompt for input 
2. Input response to Another go? (A$) 
3. If replay required (A$ = ‘‘Y’’) then GOTO Module 1,3 
4. If A$ not “Ү” then print end message 
5. Stop 


Notice that (although this is a program that has been modularised 
rather artificially to demonstrate the principles in a short program) the 
program consists of an introductory section, then a main program loop 
with both conditional and unconditional calls to subroutines, within a 
short main program loop. This makes the structure of the program 
clear, and minimises the use of GOTO statements, which would be 
required in profusion if the program were written in a linear, rather 
than modular fashion. It is perfectly possible to write the program in 
this linear manner, but the structure will not be as visible. 

You should also note that the END/RERUN module is not a 
subroutine, but uses GOTO to pass control to this section from the 
main program, with a conditional GOTO to pass control back to the 
main program if required. Conditional GOTOs аге preferable 
program structures to unconditional GOTOSs, and whilst the END 
module could be a subroutine, RETURNing to the main program 
loop, further conditions would need to be inserted to pass control to 
Module 1 for a new number to be defined. The subroutine would also 
need to be exited by а GOTO for the program to stop. There is another 
solution, however, involving a nested subroutine, which we will set as 
an exercise. 


Exercises 


1 Rewrite /GUESSNUM"' with the END/RERUN module as a 


subroutine. The procedure should be as follows: 


END/RERUN SUB 


i. Prompt for player input, and get response, as before. 


181 


п. If RERUN not required, bypass 3 апа 4 below, by a GO TO 
the RETURN line. 

ш. GOSUB to GETNUMBER subroutine. This is a nested 
subroutine. The new value of N will be set by this operation. 

iv. Re-initialise TRIES as 0 and MARK as 0. 


v. Return. 


The main program loop is then returned to. The main program 
must then test whether it is to exit (rerun not required) or 
continue (new game started). We could set another marker to 
test this, but in effect we have done this by re-setting MARK ifa 
rerun is required. 

Rewrite the main program loop, so that on return from the 
END/RERUN subroutine, the program loops back only if 
MARK = 0. If MARK = 1 then the program will not loop back 
and you can either insert a GOTO to bypass all the subroutines 
to an end program procedure, or STOP the program before the 
subroutines. 

Insert an additional subroutine which prints 1;‘‘ST’’,2; 
“ND”,3;*°* RD”, and then “ТН” for other numbers into the 
“FACTORS” program (Unit N2). 

Write a program which determines how many rolls of a die are 
required to produce a total score greater than 100. Use 
subroutines to produce the random numbers for the die rolls and 
to print out the results. 

Let the computer choose a four digit number with no two digits 
alike. You try to guess the number chosen. The computer 
indicates H (too high), L (too low) or R (right) for each digit in 
turn and determines how many guesses are required to get the 
correct number. Use subroutines to create the number, input 
the operator's guess and give the response to each guess. 


182 


PART THREE 


ADVANCED BASIC PROGRAMMING 








ТАРЫ s ДАЧ 


ОЛА мМАЯООЯЯ MEAN LOW ATTO А 


SECTION O: PROGRAMMING METHODS II 


O1: Résumé 


Before we enter the arena of advanced BASIC programming let us 
recap on what we have examined and accomplished so far. 

The method to design the solution or algorithm to a computational 
problem using ‘top down’ analysis has been explained. We have seen 
how to break our problem up into sub-problems which form our 
program modules (using tree diagrams). We know how to describe the 
algorithm in concise English sentences that we call pseudocode and 
how to determine and illustrate the flow of control in the problem 
solution by drawing a flowchart. When designing our solution we 
recognise the need to use the fundamental programming tools of: 

(1) decision making 

(п) branching as a result of decisions 

(iii) direct transfer from one point in the algorithm to another 

(iv) repetition 
These control structures, as they are called, which are present in all 
computer languages, have been discussed in some depth, together with 
other important BASIC language fundamentals. The techniques of: 

(1) decision making 

(п) numeric processing 

(iii) character handling with strings 

(iv) looping through counting and condition testing 

(v) handling of output by printing and plotting 

and the realisation of modular techniques in programming by using 
subroutines have all been covered. 


WHAT'S NEXT? 


We must now consider the second phase of the programming 
method - producing the program itself. 

It 1s important to do so at this stage in the book, so that our 
programming tool kit is complete enough to investigate and use the 
more sophisticated information handling facilities to be introduced 
later in this section: 

(1) logical operations on data 

(1) character codes 

(uni) moving graphics 

(iv) graph plotting 

(v) constructing and searching lists and data arrays 

(vi) how to sort information into order 

Once these skills have been mastered our complete programming 
expertise can then be applied to real applications. 

Let's now see in this section of the text how to code our algorithms 
into BASIC language programs, and then debug, test and document 
them. 


185 


Further important design rules will be given, and finally a summary 
of our complete programming method will be provided with a 
flowchart and worked example. 


O2: Producing the Program 


We now consider the method by which a well designed, tested and fully 
documented program is produced. 

Given our algorithm - which we have written out in steps in a 
description we call pseudocode — together with our flowchart — which 
shows how the steps of the solution are combined in sequence for the 
computer to solve the problem - we must now: 


1. CODE THE ALGORITHM IN SINCLAIR BASIC 
2. DEBUG AND TEST THE PROGRAM 
3. DOCUMENT THE PROGRAM 


O3: Coding and Design 
CODE ON A ONE TO ONE BASIS 


If the description of the algorithm is correct then coding on an almost 
one to one basis from statements in the pseudocode or the flowchart is 
possible. If you cannot code from the flowchart or pseudocode then 
further refinement of the algorithm is necessary. 

Pseudocode descriptions in formal mode of the BASIC language 
control structures for decisions and loops are given later in this section. 
You will notice that the description itself is indented and concise, with 
the terms almost the same as BASIC statements. This is not unusual as 
BASIC was designed to do this very thing and 1s English-like in its 
syntax. 

To be able to code at all you must of course: 


KNOW THE BASIC LANGUAGE AND ITS RULES 


Hopefully it is the right language for the job. On the ZX81 and 
Spectrum you don't have much choice! Actually it is a question of ease 
of programming specific applications that generates different 
languages. Most things can be done in BASIC, although perhaps not 
efficiently or elegantly. It is often useful to identify the kind of 
processing that will be required. When designing the algorithm 
consider whether the problem is a scientific or a business application, 
whether extensive calculations will be performed or large amounts of 
list processing done, whether the data is extensively numeric or string 
and whether the program will be interactive with much user dialogue. 

When coding, avoid spelling and formatting mistakes. Sinclair 
BASIC is powerful in that it is one of the few available single keystroke 


186 


BASICs, hence you cannot make spelling mistakes on instructions or 
commands because the whole instruction is keyed in at once. However, 
mistakes can still be made when assigning variable names and in 
PRINT and REM statements. 


DEFINE AND CONTAIN EACH MODULE 
WITH REM STATEMENTS 


For example: 
100 REM * SORT MODULE * 
200 REM * THIS MODULE SORTS STRINGS * 


500 REM * END SORT * 
TERMINATE YOUR PROGRAM PROPERLY 


You may have noticed that Sinclair BASIC does not need a special 
end-of-program statement. We can, however, put one in using a REM 
statement. For example: 


500 REM * END OF PROGRAM * 


Тһе 7Х81 and Spectrum do not process but only note REM 
statements. When the above line runs, the program will finish 
elegantly with a 0/500 message. 

We can also stop a program with the STOP statement. Main 
modules should finish like this with subroutines programmed at higher 
line numbers terminated with a REM * END * statement. When 
terminated with STOP a message 9/line number (a 9 Stop (Line 
number): 1 statement on Spectrum) will be given. 

REM * NAME OF PROG * 
10 REM * MAIN MODULE * 
20 GOSUB 500 
30 STOP 
40 REM * END MAIN * 
500 REM * SUBROUTINE * 
600 RETURN 
700 REM * END SUBROUTINE * 
800 REM * END OF PROGRAM * 


We could also use a GOTO 800 at line 30 to terminate execution on 
the last program line. 


ALWAYS CODE ACCORDING TO THE LOGICAL ORDER 
OF PROCESSING 


This is usually ensured if you code from a flowchart, with your 


187 


flowchart structured into modules, i.e. flowchart groups for the 
modules in the program. 

Take care with the control structures and avoid unnecessary 
branching, especially with GOTO instructions. Try to make your 
programs both readable and efficient — but first make them readable! 


USER FRIENDLY PROGRAMS 


Design your programs with the user in mind - and that includes you! 
Directions to users should be concise and as few as is necessary, both in 
the program and in the user guide if your program is large enough to 
merit one. 

Where the user needs a number of instructions to operate the 
program then these can be built into an optional ‘help’ module or 
subroutine. 

100 REM * USER INSTRUCTION * 

110 REM * DIRECTS USER TO HELP SUBROUTINE * 

120 PRINT “ FOR INSTRUCTIONS TYPE HELP 
OTHERWISE TYPE C " 

130 INPUT A$ 

140 IF A$ - *HELP''THEN GOSUB 1000 

150 REM * END USER INST * 


1000 REM * HELP SUBROUTINE * 


1200 RETURN 
1210 REM * END HELP * 
Users usually require to know: 

~ how to run the program 

— what form of input data is required 

— what output is produced 
Your program should check on the range and type of input data. If the 
input data is out of range or incorrect the program should not stop with 
an error, but continue with a message to input correct data. 

After you have designed a program to do a specific task it may be 
worthwhile to change it to be as general as possible — i.e. do several 
similar tasks. As you become more skilled and confident in 
programming you will be able to generalise and write a subroutine that 
enables users to select options from a menu. This is exactly similar to 
the exercise you have seen in multiple decision structures. See the 
"CASSFILE'' program in Section V, for a ‘‘menu-driven’’ program. 
More “‘user-friendly’’ tips are given in the section on documentation, 
and some useful routines in Unit V2. 


188 


DESIGNING PROGRAM LAYOUT 


You must make your program readable. The program design will be 
modular and contain specific identifiable segments, subroutines and 
modules. These should be labelled in the design of the algorithm and 
transferred in the coding process. 
(1) EACH MODULE SHOULD BE TITLED AND LABELLED 
TO INDICATE ITS FUNCTION. FOR EXAMPLE: 
10 REM “AVERAGE” 
20 REM * PROGRAM AVERAGES ANY NUMBERS 
INPUT * 
3 REM * 
40 КЕМ * USER ROUTINE * 
50 REM * CHOICE OF NUMBERS INPUT * 
60 PRINT “HOW MANY NUMBERS DO YOU WISH 
TO АУЕКАСЕ” 
70 INPUT N 
80 DIM A(N) 
9) REM * INPUT ROUTINE * 
100 REM * NUMBERS INPUT TO ARRAY * 
110 PRINT “INPUT NUMBERS" 
120 FORI=1TON 
130 INPUT A(I) 
140 NEXT I 
150 REM 
160 REM * PROCESSING ROUTINE * 
170 REM * COMPUTES AVERAGE * 
180 LET SUM-0 
199 FORJ=1TON 
200 LET SUM = SUM +A(J) 


210 NEXT J 
220 LET AVERAGE - SUM/N 
230 REM 


249 REM * OUTPUT ROUTINE * 
250 PRINT “THE AVERAGE OF" 
260 FOR K=1 TON 

270 PRINT A(K); ”’; 

280 NEXT K 

290 PRINT “IS ”; AVERAGE 

300 REM 

310 REM * END AVERAGE * 


(2) DESIGN YOUR PROGRAM SO THAT RELATED 
STATEMENTS ARE TOGETHER 


For example, input — processing — output statements: 
() All input statements will be at the beginning of a simple 
sequential program, processing in the middle, and 
output normally at the end. 


189 


(3) 


(4) 


(9) 


(üu) For a modular program, input, processing and output 
routines will be separate modules or groups of statements 
within a single module. 

(ш) Subroutine modules will usually be placed separately at 
the end of a program. 


INSERT REM STATEMENTS BETWEEN PROGRAM 
MODULES AS SEPARATORS 
Program modules are then easily identified. Use blank REM 


lines or lines of asterisks. 


PLAN YOUR PROGRAM LAYOUT BEFORE CODING 
The printed listing of your program is important. Choose a 
maximum line width. Break longer lines into shorter ones in 
REM statements by using spaces. Compensate for overrun. For 
example: 
10 REM * AAAAA 

AAAAA 

AAAAA * 
You will not be able to do this with other BASIC statement lines. 


YOUR LAYOUT SHOULD TRY TO REFLECT THE 
MODULAR STRUCTURE OF YOUR PROGRAM 


190 


Indented statements are not possible on the ZX81 or Spectrum, 
unfortunately! 


DESIGNING PROGRAM OUTPUT 


For the user the output is the most important part of the program. 
Take time planning it. The output instructions in Sinclair BASIC are: 
PRINT, PRINT AT, PLOT, LPRINT, COPY, TAB, plus graphics 
commands. 
() RESULTS SHOULD BE OUTPUT WITH RELATED 
ITEAL 
Label all your numerical output: 
єн. 1974 £5678.65 
instead of 1974 5678.65 
e.g. AVERAGE AGE OF BOYS IS 15 YRS 3 MONTHS 
rather than 15 3 


(i) DISPLAY LARGE AMOUNTS OF OUTPUT AS A TABLE, 
HISTOGRAM OR GRAPH, AND GIVE TITLES. 


For example: 


TABLE 1: NET INCOME FOR B. JONES 
FOR YEARS 1978-80 


Box your tables if possible. 
The user should not have to look up the program listing to see 
what the numbers in the output mean. 
au) DESIGN YOUR OUTPUT TO BE EASY TO READ 
Plan it to be attractive to any user of your program and, of 
course, yourself. Graphics is a powerful tool for this. 
(iv) ALIGN, SPACE AND JUSTIFY THE OUTPUT 
Plan your output with reference to the screen size and divisions. 
For tables — align information central to the heading 
align signs 
right justify numbers 
left justify characters. 
(There are routines in the text for doing this). For example: 


876-340 JIM SMITH 
27-210 HUNG FO 
453-003 SARAH JAY 
1-025 DRACULA 
























NUMBERS 
15.003 
815.231 
- 4.000 
– 100.100 
Fill in with zeros to get decimal placing correct. 
(v) USE SPACE CAREFULLY 
Sinclair computers use expensive printer paper! Print output 
horizontally wherever possible. For example: 
TABLE OF POWERS OF 2 
2 
4 
8 
16 
32 etc 


should be: 
TABLE OF POWERS OF 2 


2 £ 8 16 32 
64 128 256 512 1024 


(vi) DO МОТ OVERDO EXPLANATIONS 
Be succinct! 


(уп) MAKE YOUR ABBREVIATIONS CLEAR 


x = 25 
NDTC =25 
NUMBER OF DAYS TO CHRISTMAS = 25 


(vii) DISPLAY INPUT DATA AS AN OPTION 
Allow checking of input data before processing. 
Make your program check for incorrect or bad input data. 


MODULAR DESIGN 


We break problems down into sequences of steps to produce programs 
in which different kinds of activities are separated out. These 
distinctive program modules are our SUBROUTINES or SUB- 
PROGRAMS. Each module has its own name and address, but in 
BASIC we usually refer to program modules by address only, as with: 
GOTO 100 and GOSUB 3300 

where the address is the line number of the first statement in the 
module. 

We can address sub-programs or modules by name by assigning the 
name and address of the module at the start of the program. For 
example: 


10 REM * ASSIGN MODULE NAMES * 
20 LET INPUT DATA = 1000 
30 LET PROCESSING = 2000 


192 


40 LET OUTPUT DATA = 3000 

59 REM * END MODULE ASSIGN * 
60 REM 

70 REM * MAIN * 

80 GOTO INPUT DATA 

90 GOSUB PROCESSING 

100 GOTO OUTPUT DATA 
110 STOP 


1000 REM * INPUT DATA MOD * 


1500 GOTO 90 

1600 REM * END INPUT * 

2000 REM * PROCESSING SUBROUTINE * 
2500 RETURN 

2600 REM * END PROCESSING * 

3000 REM * OUTPUT DATA MOD * 

3500 GOTO 110 

3600 REM * END OUTPUT MOD * 

4000 REM * END PROG.* 


There are good reasons for modular design and the use of subroutines 
and sub-program modules. The logic of the program, i.e. its flow, is 
easier to follow. The clarity of the structure of the main program is 
improved whilst program design is proceeding by referring to the 
number or name of the module initially, instead of starting to write out 
the code of the module at that point. The module can be coded as a 
separate entity. 

Independent testing of modules is possible, but care must be taken 
that all variables have been declared and have their correct values at 
the start of the module. Debugging 1s simpler with this approach, since 
the module is isolated. You can leave the coding of a module until a 
later stage, but you must know what it will do when coded. 

If a module has to be used several times in a program from different 
places it need only be written once and called (into action) from these 
points by reference to its line number or name. 


193 








Program modules can be designed to run sequentially: 


START 


MODULE 1 
INPUT 


MODULE 2 


PROCESSING 


MODULE 3 
OUTPUT 


STOP 





This structure is convenient for simple programs. However, programs 
can be structured in terms of subroutines and sub-programs being 
called from a short and simple main program module. 


START 


MAIN 
a MODULE 


MODULE 2 
MODULE 3 


194 







This structure is convenient for longer, more complicated, programs 
with many modules and nestings. 

Subroutines automatically return to the next line in the main program 
through the RETURN statement. Other modules are called by GOTO 
(line number) and return by GOTO (line number) instructions. 
GOTO MUST BE USED WITH THOUGHT AND CARE AND 
NOT EXCESSIVELY. Use a GOSUB unless a return to a different 
point in the main module is needed or a multiple return is possible as a 
result of a decision to be made within the module. 

Nested modules can be treated as other modules and called from 
within the subroutine or sub-program, by GOSUB and GOTO 
instructions. Nested loops must be contained within the same module, 
however. 





CONTROL STRUCTURES IN SINCLAIR BASIC 


(1) Each control structure is a program module. 

(2) A formal pseudocode description of each structure is given of the 
general form of the control structure. 

(3) A flowchart description is given of the general form. 

(4) The BASIC version is given of the general form. 

(5) A simple example illustrates the BASIC form of the control 
structure. 

(6) Structures will be written in indented form in the pseudocode 
version for clarity. You cannot indent in Sinclair BASIC 
program listings. REM statements must be used to show the 
start and stop lines for program modules. 

(7) P is a processing operation. It can be a single instruction, a 
statement or a group of statements. 

(8) In the formal pseudocode each structure will commence with the 
title module (abbreviated to mod), and end with the statement 
endmodule (abbreviated to endmod). 

(9 In BASIC cach structure will be bounded by 
REM*STARTMOD* and REM*ENDMOD* statements. 

(10) Flowcharts will be bounded by START and STOP symbols. 


The structures summarised are: 


A) Decision Structures 
(1) Single decision 
IF-T HEN structure 
(п) Double decision 
IF-T'HEN-else structure 
(ш) Multiple decision 
Case structure 


195 


B) Loop Structures 


(i) repeat-forever loop structure 

(ii) repeat-until structure 

(iu) while-do structure 

(iv) FOR-NEXT structure 
The names of the structures are implemented as actual 
programming language structures in other languages and some 
forms of BASIC. The FOR-NEXT structure is a special form of 


the while-do loop, given a specific implementation in BASIC. 
A. DECISION STRUCTURES 


() SINGLE DECISION: The IF-THEN structure 
Meaning: IF (condition is true) THEN (do something) 


Pseudocode Flowchart 


mod 
if (condition) 
then P 
endif 


endmod 


BASIC 

10 REM*START MOD* 
20 IF (COND) THEN P 
30 REM* ENDMOD* 





Example 
Input a number and if it is positive, print it. 
Pseudocode BASIC 
mod 10 REM*START MOD* 
input A 20 INPUT A 
If A > Q 30 IF A>@ THEN PRINT A 
then print A 40 REM*END MOD* 
endif 
endmod 


196 


(i) DOUBLE DECISION: The IF-THEN-else structure 
Meaning: IF (condition is true) THEN (do something) 
otherwise (if condition is false) do something else. 


Pseudocode Flowchart 


START 


mod 
if (cond) 
then P1 
else P2 
endif 


endmod 





BASIC 

10 REM*START MOD* 

20 IF (COND) THEN GOTO 50 
30 (FALSE TASK P2) 

40 GO TO 60 

50 (TRUE TASK P1) 

60 REM*ENDMOD* 


To perform the true task (P1 in the pseudocode) first, the BASIC 
implementation of the structure would test the complement of 
the condition, so that in the program below, for example, A>B 
would be replaced by A<B, and lines 50 and 70 swapped. Note 
the standard form of complement would be B< = A, but we have 
defined the input numbers as unequal in this case. 


197 


Example 


Input two unequal numbers and print the largest. 


Pseudocode BASIC 

mod 10 REM*STARTMOD* 

input A,B 20 INPUT A 

ifA>B 30 INPUT B 

then print A 40 IF A» B THEN GOTO 70 

else print B 50 PRINT B 

endif 60 GOTO 80 

endmod 70 PRINT A 


80 REM*ENDMOD* 


(ш) MULTIPLE DECISION STRUCTURE: The case structure 


With this structure we want the program to select and perform 
one of several alternative tasks. 

The conditions in this case structure are sequential, not 
nested and mutually exclusive. 


Pseudocode Flowchart 


mod 
case 
if (condition 1 is true) 
then P1 
if (condition 2 is true) 
then P2 
if (condition 3 is true) 
then P3 
end case 
endmod 





198 


BASIC 


10 REM*STARTMOD* 
20 IF Cl THEN P1 

30 IF C2 THEN P2 

40 IF C3 THEN P3 

320 REM*ENDMOD* 


Example 


Test whether a number input is positive, zero, or negative, and 
print the result. 


Pseudocode Flowchart 





mod 
input A 
case PRINT 
if A<0 NEGATIVE 


then print “МЕСАТІУЕ” 
If А = 0 
then print “ZERO” 
if А>0 
then print “POSITIVE” 
endcase 
endmod 






PRINT d 
PRINT 
POSITIVE 






199 





BASIC 

14 REM*STARTMOD* 

20 INPUT A 

30 ЕА < 0 THEN PRINT “NEGATIVE” 
40 IF A-0 THEN PRINT “ZERO” 

5) IF A>@ THEN PRINT “POSITIVE” 
60 REM*ENDMOD* 


Alternatively, we can use conditional and unconditional GOTO 
statements to implement this structure. This would be 
appropriate if the processing section of a program after the 
decision were several statements long, rather than the single 
instruction available on the ZX81. Spectrum users can add more 
instructions on the same line. They should be restrained in using 
this facility. 


10 REM*STARTMOD* 

20 INPUT A 

30 IF A< 0 THEN GOTO 60 
40 IF A-0 THEN GOTO 80 
50 IF A>@ THEN GOTO 100 
60 PRINT “NEGATIVE” 

70 GOTO 110 

80 PRINT “ZERO” 

90 GOTO 110 
100 PRINT “РОБІТІУЕ” 
110 REM*ENDMOD* 


В. LOOP STRUCTURES 
(1) The repeat — forever loop 


Meaning: None. The only conceivable result is the program 
halting with an arithmetic overflow report. 


Pseudocode Flowchart BASIC 
(такт) 10 REM*STARTMOD* 
START 
20 P 
30 GOTO 20 
mod 
40 REM*ENDMOD* 
repeat 
P 


forever 
endmod 


200 


(i) 


This structure is for demonstration only. Avoid using it in 
programs! It can sometimes occur in error. Use BREAK if you 
suspect your program has entered such a loop (because nothing 
happens). 


The repeat — until loop 


Meaning: Repeat processing until a condition is true. 

These structures loop until a specific termination condition is 
met, for example until a counter reaches a certain value or until 
a dummy or sentinel value 1s input. The important characteristic 
of this loop structure is that the repeat test (or exit test) is at the 
bottom of the loop, after the processing ‘body’. The program 
lines making up the body of the loop (P) will be executed at least 
once. The repeat condition can use any conditional operator or 
its complement (reverse). 

e.g. equals 4—0 not equal 
- <> 


Use of the complement often leads to a more elegant program. 


Pseudocode Flowchart 


mod 
repeat 
P 
until (condition is true) 
endmod 





BASIC 

10 REM*STARTMOD* 

20 P 

30 IF (COND) THEN GOTO 50 
40 GOTO 20 

50 REM*ENDMOD* 


201 


BASIC using complement 


10 REM*STARTMOD* 

20 P 

30 IF (COMP COND) THEN GOTO 20 
40 REM*ENDMOD* 


Exit requires no specific instruction. 
Example 


Input and print strings until the sentinel value “LAST” is 
input. 


Pseudocode Flowchart 


START 








mod 
repeat INPUT Ag 
input A$ 
print A$ 
until A$ = LAST 
endmod 
PRINT Ag 
Ag-LAST ? 
BASIC 


10 REM*STARTMOD* 

20 INPUT A$ 

30 PRINT A$ 

40 IF A$=‘‘LAST’’ THEN GOTO 60 
50 GOTO 20 

60 REM*ENDMOD* 


202 


Complement Version 

10 REM*STARTMOD* 

20 INPUT A$ 

30 PRINT A$ 

40 IF A$<>‘‘LAST’’? THEN GOTO 20 
50 REM *ENDMOD* 


(ш) While — do structure 


Meaning: While a condition holds (TRUE) keep repeating the 
process until the condition is broken (FALSE). 

The condition can be, for example, that a loop-counter 
variable value is not equal to its final value (IF N<10 THEN..). 
The process will then repeat until it is. The condition may also 
be set so that a sentinel value has not occurred (IF N<>6 
THEN). These conditions are set so that the true pathway is the 
process task, and the false is the exit. 

The While — do loop is characterised by having the repeat test 
carried out prior to the body of the loop (i.e. at the top). No 
processing will happen if the repeat test is false at the first 
encounter, i.e. the body of the loop is never entered. 


Pseudocode Flowchart 


START 








mod 
while (condition is true) 
do P 
endwhile 
endmod 


BASIC 
10 REM*STARTMOD* 
20 IF (COND) THEN GOTO 40 


30 GOTO 60 
40 P 
50 GOTO 20 


60 REM*ENDMOD* 


203 


(iv) 


Using the complement of the repeat condition gives a neater 
program. 


Complement Version 


10 REM*STARTMOD* 
20 IF (COND) THEN GOTO 50 
P 


40 GOTO 20 
50 REM*ENDMOD* 


Example 


While the value of the square of consecutive integers is less than 
100, print them on the screen. 


Pseudocode BASIC (complement) 
mod 10 REM*STARTMOD* 
п = 1 20 LETN=1 
while п*п< = 100 30 IF N*N>100 THEN 
do print n*n GOTO 60 
n=n+1 40 PRINT N*N 
45 LET N=N+1 
end while 50 GOTO 30 
endmod 60 REM*ENDMOD* 


FOR - NEXT Loops 

FOR - NEXT loops are a special BASIC structure for repeating 
a process a stated number of times. They are in fact While — do 
loops and have the repeat test at the top of the loop. 


Example 


Print the values of the first ten integers. 


Pseudocode BASIC 
mod 10 REM*STARTMOD* 
n= 1 20 FOR N=1 TO 10 
While n < = 10 30 PRINT N 
do print n 40 NEXT N 
п=п+1 50 REM*ENDMOD* 
епа while 
епатоа 


FOR - NEXT loops have their own special flowchart symbol, 
because they are used so extensively in BASIC: 


204 


Ordinar Special 





This is a condensed version. It groups together 
the FOR — NEXT — STEP instruction elements, 
which the standard form separates. 





This illustrates both a 
While do and a FOR- 
NEXT structure. 


O4: Program Development 


Program Development involves the activities of DEBUGGING your 
program of errors, TESTING to see if it behaves as specified and gives 
the desired results, and DOCUMENTATION which tells users how to 


run the program. 


DEBUGGING 


The Sinclair machines have good editing facilities and error messages. 
Those on the Spectrum have brief statements of the error type, those on 
the ZX81 have just a number or letter. 

Although it is inefficient to correct errors one at a time (because there 
is seldom only a single error since programming mistakes tend to 
compound one another), error messages on the machine are produced 
singly, since an error stops the computer from running. Thus we must 
deal with the errors as they occur in the program sequence. You may 
notice a number of errors on carefully looking through the listing. Any 
you spot should be edited out at once. 

GET TO KNOW YOUR COMPUTER ERROR CODES 
This will happen automatically in time (as you make mistakes!), but it 
is worthwhile studying the codes. They define the ways in which 'run- 
time' errors occur, and an understanding of them will help you avoid 
bugs. 

205 


EXIT 


Keep a note of mistakes you have made and how you 
corrected them. This will be valuable for future reference. 
This should become an automatic part of your personal 
documentation. Keep a copy of old program listings. Record the errors 
you have made, the corrections you tried but which did not work, and 
what you learned in developing the program. 
Trace the impact of any error through the program. 


SYNTAX ERRORS 


These are caused by BASIC statements you key in which do not obey 
the precise language rules (syntax rules) of Sinclair BASIC. The syntax 
errors are detected by the LINE INTERPRETER which 
automatically checks each line you key in when you press the 
NEWLINE (ENTER) key. 

If there is an error the interpreter will place the SYNTAX ERROR 
cursor just before the first error it detects on the line. This may be at 
the end of the line if the interpreter finds that something else should 
have been placed there. To correct this type of error you must compare 
the syntax you have written with the rules of BASIC. 

Typing instructions incorrectly cannot occur on the Sinclair 
computers as the BASIC 15 single key-stroke. In other BASICs you 
must type P,R,I,N,T, for PRINT. Instructions in general are 
automatically placed in the correct order along a line (i.e. the order of 
line number - instruction — operand), since they are taken care of by 
the mode controller which sets the cursors in the correct sequence. 

Errors which can occur are: 

1 Omission of line number 
Line number too large (29999) 

Line number negative 
Line number non-integer 
Omission of delimiters: 
brackets (must be paired) 
commas 
semicolons 
quotes 
colons (on the Spectrum) 

6 Typing in of improper variable names 

7 Incorrect logical expressions 
There can be more than one error per line. The S-cursor will re-appear 
in the line when you try to enter it into memory. The line edit facility is 
comprehensive and easy to use on the ZX81 and Spectrum. 

You must correct your mistakes, and keep trying to ‘compile’ the 
line into correct BASIC syntax (to be entered into memory). When 
successful, the program line will appear at the top of the screen. 

The syntax error check ensures no nonsense lines (from the 
computer's point of view) are entered. It cannot help you in coding 
correct sequences of program lines, or prevent logical errors. 


сл ны оо ho 


206 


PROGRAM LOGIC ERRORS 


These are the effect of bad logical design of the program. They can be 
avoided if care is taken in the design and coding of the program. Ifa 
program produces incorrect results then there is an error in the flow of 
logic in the program. This may only occur with certain values of data. 

If each program section or module has been tested independently 
then the linking of the modules is incorrect. We can test program 
sections as follows: 


1) Insert a temporary breakpoint into the program, at the 
appropriate point. 

2) Print out values of intermediate results, to the screen or printer. 

3) It is most important to print out the values of variables used in 
making a decision and those used in loops, either counter loops 
or FOR - NEXT loops. 

4) Go back to the pseudocode or flowchart and modify the steps 
which are in error. ‘Walk through’ the algorithm, using a 
flowchart, to check the step sequence, and hand trace the 
program with selected values of data and/or variables. Be 
careful! Often changes in one part of the algorithm cause 
changes in the others. It is no use solving one problem if it causes 
another! 

3) Change the documentation if necessary. Note down the changes 
you have made, or lines you have deleted. Keep program 
listings. 

6) Re-test the complete program, using a variety of data. 


Each testing statement in a complex program should be headed by a 
remark statement. 


1000 REM - DEBUG 


— (Testing Statements) 


- REM - END DEBUG 
These temporary REM statements are later deleted by keying in their 
line numbers, as are the testing statements. It is very easy to leave in 
test instructions unless they are marked. 


INSERTING BREAK POINTS 


We can stop a program at any point and obtain the values of variables, 
expressions, etc. to test calculations or check for errors. We do this by 


207 


Inserting a group of statements which will output the values we want 
and then stop the program. 


qM < ADD TEST OUTPUT OF VARIABLES 
МШ < INSERT STOP STATEMENT 


CONT will restart the program. 

Individual modules or sections of program can be tested this way. 
We do, of course, have to RUN the program from the required module 
line number. Care should be taken when this is done that variables 
needed in the module have been declared properly and that the values 
of parameters passed to the module are as required. Remember that 
you can INPUT the values of variables directly if necessary, using the 
command mode, and using LET statements: 

LET X(2) = 20, etc. 
The value of any variable at the point the program crashed can also be 
obtained by keying a statement without the line number, and again 
using the computer in command mode: 
PRINT A$ 
LPRINT X(3) 


The commands RUN N (where N is the line number we wish to run 
the program from) and GOTO N enable us to run the program starting 
at any point. Using GOTO N does not negate the initialisation of 
variables that occurs 2 the program has already run. For example, if 
we input: 


10 LET A=1 
20 LET B = 2 
39 PRINT A,B 


and then key in GOTO 30, we get the error report ‘2/30’ (ZX81) or ‘2 
Variable not found 30:1' (Spectrum) meaning an undefined variable 
was found. If we RUN the program, we can then use GOTO 30, and 
the program signals successful completion. 


RUN-TIME ERRORS 


These are a result of programmer carelessness and do not prevent the 
interpreter from translating the program. They make the program 
crash when you attempt to run it, that is they prevent the program 
from running to completion. Common run-time errors are: 

1) undeclared or unidentified variables 

2) arithmetic overflow 

3) lack of data for processing 


208 


4) failure to complete loop increment and subroutine section 
statements 

5) subscript out of range 

6) memory full 

7) screen display file full 

8) integer out of range 
As we have seen, run-time errors cause diagnostic system messages to 
be printed. ‘These appear at the bottom of the screen and are called: 

ERROR CODES 

These errors can then be traced through the type of error given by the 
code and the line number at which the program stopped. 


ERROR CODES 


Error codes or Report codes are presented on the screen when a 
program stops for any reason, either as a result of successful 
completion (no more program lines), an instruction or command 
(STOP, BREAK), or a run-time error. 

On the ZX81 the codes have the form E/N, where E is the code for 
the type of error and N is the line number where the program was 
stopped (STOP or BREAK), or where an error occurred. N is @ fora 
direct command. This is an example of an error code on the ZX81 
which is printed on the screen when an arithmetic overflow (number 
larger than about 10% generated) occurs in line 60 of the program: 

6/60 
The Spectrum gives an extended error report code, with a brief 
statement in the form: 
E Statement N:S 

where E is the report code, the statement is the reason for stopping 
(with BREAK or STOP or program completion) or type of error. N is 
the line number, but since the Spectrum can have multiple line 
statements, the S number indicates which statement on the line the 
report code refers to. We are not using multiple line statements in this 
text, so S will always be 1, meaning the first (and only) statement on 
the line, unless after the THEN in an IF... THEN statement, which 15 
treated, like a colon, as a statement separator. 

The Spectrum's version of the example given above (the ZX81’s 
arithmetic overflow error code) is: 

6 Number too big 60:1 
Report codes are crucial aids to debugging programs. Without them 
we would know only that we had an error, but not where it occurred or 
what type of error it was. The error reports indicate both of these items 
of information. 

It is important to understand that the cause of an error may come 
earlier in a program than the line where the program stopped. For 
example, a code 2 error (variable not found), occurring in line 100 of a 
program might be caused by a mis-spelt variable name in line 100 (not 


209 





the same as the variable you meant it to be — putting GUES when you 
meant GUESS, for example). It could also be the result of not having 
assigned the variable earlier in the program. If the error causing the 
program to halt is not apparent from the line given in the error report, 
the program flow must be traced backwards to find the prior cause. In 
some cases this can be extremely difficult to track down - for example, 
where a numeric value wrongly defined or generated by the program 
causes another expression to cause an arithmetic overflow. Tracing 
techniques must be used. 

Lists of Error codes and their meanings for the ZX81 and Spectrum 
are given in Appendix II. 


TESTING AND VERIFICATION 


Verify that your program works by testing it with Test Data 


Testing comes after debugging a program. Its purpose is to ensure that 
the program is logically correct, produces correct answers and meets 
the specification of its purpose. 
1 First test each module separately 
Each procedure and subroutine should be treated as if it were a 
separate program. 
Test for (i) good data - the expected type and range of inputs. 
(1) bad data — out-of-range and incorrect type inputs. 
Try to ensure each procedure ‘fails softly’. For bad data (particularly 
in any data entry module) following each input a check routine or 
procedure should be used to give an error message if range is incorrect 
or check type of input and correct syntax. This is best done with 
strings, which are more flexibly handled. See Unit V which deals with 
input checks at length. 
2 Combine the modules and test the complete program 
If there is a logical error (1.e. program does not produce the intended 
results) insert additional test statements which will: 
(i) Output intermediate results. 
(11) Output values of variables at each stage. 
(iii) Output results of expressions at each stage. 
(iv) Output values of the loop counter at each pass. 
(v) Output results of array manipulation after each 
operation. 
(vi) Output values of parameters before and after subroutines 
entry and return. 
3 Handle exceptions 
(1) Test all data in the program. 
(11) Screen all data. 
(111) Process only good data. 
(iv) Output bad data saying why it was bad. 


210 


4 Let your program stop elegantly 
(1) When there is no data input or data available, the 
program should tell you so. 
(1) Sinclair BASIC programs are interactive. The user сап 
control program continuation with: 


910 PRINT “PROCESSING ENDED - MORE 
DATA? ANSWER YES OR МО” 

920 INPUT A$ 

930 IF A$ = “YES” THEN GOTO 100 

940 PRINT “GOODBYE” 

950 STOP 

960 REM PROGRAM END 


5 Rewrite the program until you are satisfied with it 
Remember the program should be - structured 
— easy to read 
— easy to understand 
— handle exceptions 
— be as efficient as possible 
— documented 
and it must solve the problem as specified! 
6 Put clarity before efficiency 
To be good a program algorithm does not have to be clever, difficult to 
understand or run super-fast. If you do not understand how the 
algorithm works do not use it — rewrite and re-design or use another 
method. 
Programs will work correctly if the rules of the language are obeyed, 
and the program will work to specification if the algorithm 1s properly 
designed. 


DOCUMENTATION 


ANNOTATE AND DOCUMENT YOUR PROGRAM AND 
CREATE A READABLE PROGRAM 


1 Write an explanation for each program module or segment. At 
the beginning of each segment provide suitable comments which 
explain: 

(1) the purpose of the algorithm 
(2) the variables and their significance (the values they 
store) 
(3) the results expected. 
2 Use comments only where necessary: 
(1) don't comment each program line 
(2) don't explain the obvious 
(3) at the beginning of the program provide a block of 


211 


10 


comments that explain the program at each module and 
provide a comment which explains what the module does 
in relation to the program. 
Clear comments should appear separated from program code. 
The clearest comments are framed. For example 


19 REM * * * * * * * * 

20 REM * SUBROUTINE TO * 

30 REM * CALCULATE N TO 2 D.P. ы 

40 КЕМ * i 

50 REM * * * * * * * * 
Lines of asterisks provide visible dividers between sections of 
program. 


Use comment in the program and in the output to the screen or 
printer. 

Use blank REM lines as separators in the program. 

For large programs write a reference document: 

(1) Describe the algorithm you used. If it is not original you 
should include a note of its source, author, version, and 
type of computer it was written on. 

(ii) Explain how you wrote the program, the reasons for 
writing it, the type of computer used and memory 
required. 

(ii) Make a note of areas that may need improving, or could 
be modified for different purposes. 

(iv) Which modules are general (menus, subroutines), and 
which require specific kinds of input. 

(v) Explain the scope and limitations of the program. 

(vi) Include your name, and the date of production. 

List the tests you made and data used. Reproduce some of the 
results of the tests. 
List performance tests (e.g. how long it takes the program to 
run). 
Give user instructions and reproduce the output of a run and 
explain to the user how he uses the program. 
Give the program characteristics. Explain any abnormal 
behaviour of the program (e.g. response to bad input). 
Write a brief USER GUIDE. This is mot for the computer 
expert. It should explain: 

— the purpose of the program 

— the algorithm 

— how to run the program 

— what input is needed 

— what results are printed 

— how to use the menu (if included) 


O5: THE COMPLETE PROGRAMMING METHOD 


SUMMARY: THE STRUCTURED PROGRAMMING METHOD 


1. | PRODUCE THE ALGORITHM 


State the Problem fully 


1.4 


1.3 


1.3 


1.4 


1.1.4 
1,2,2 


State the problem 
Understand what is to be done 


Research the Problem 


1.2.1 


1,24% 
15,4 


Research апа analyse the problem to see how the 
computer can handle it 

Identify all formulae and relations to be used. 

Identify all data involved 


Design the algorithm 
Use top down structured methods: 


152,1 
1,5,2 


1.5.3 


1.3.4 


1.2.9 


1.3.6 


Break the problem up into sub-problems ог modules. 
Use a structure diagram or tree diagram to help in 
breaking down the problem. 

Start classifying modules or parts of modules as: 
INPUT 

PROCESSING 

OUTPUT 

Utilise the fundamental control structures in the modules 
— Decision structures 

— Transfer structures 

— Loops 

- Subroutines 

- Nested structures 

— Subprograms 

Set up a DATA TABLE in which all data types are 
classified as 

Variables 

Constants 

Counters 

Functions - if using a Spectrum and the DEF ЕМ 
instructions 

Define the algorithm further until coding it into a BASIC 
language program is an easy and obvious exercise. 


Describe the algorithm in Pseudocode and Flowchart form 


1.4.1 


1.1.2 


1.4.3 


Write out the final algorithm (now in modular form) in 
small steps in an abbreviated English style called 
Pseudocode. 

Each module should be treated separately and !abelled. 
Illustrate the logical flow of control in the algorithm by 
constructing a flowchart. 

Test the algorithm, if necessary using a hand trace or 
walk through. 


213 


2. 
2.1 Code the Algorithm in SINCLAIR BASIC 
2.1.1 Code on a direct basis from the pseudocode or flowchart 
description in line numbered BASIC statements, module 
by module. 
2.1.2 Implement the fundamental control structures, used in 
their SINCLAIR BASIC versions. 
2.2 Debug and Test the Program 
2.2.1 Debug the Program. Check the program variables against 
your algorithm test. Correct syntax, run time, and logical 
errors. 
2.2.2 Test the program for further logical errors. Run the 
program with sample data. 
2.3 Document the Program 
For a full documentation, you should: 
2.3.1 Produce a programmers’ guide consisting of: 
pseudocode 
flowchart 
variable table or data table 
program listing 
test results or sample printout. 
2.3.2 Detail the steps that producing the program involved. 
2.3.4 Write a user guide. 


214 


PROGRAMMING: SUMMARY OF METHOD IN FLOWCHART FORM 


This provides a diagrammatic version of the summary of structured 


START 


FIND OUT WHAT YOU 
HAVE TO DO. 


programming: 


STATE THE PROBLEM 




















DRAW A STRUCTURE 
DIAGRAM OF HOW YOU 
ARE GOING TO SOLVE 
THE PROBLEM. 

(THE ALGORITHM ) 









WRITE A 
DESCRIPTION OF 
THE ALGORITHM. 


PRODUCE A 
FLOWCHART 





CONDUCT A 
WALKTHROUGH 


ERRORS 
? 


No 


В) 


215 







CODE INTO BASIC 


FIND ERRORS AND 
CORRECT 






RUN A TEST 


ERRORS 
? 


No 


TEST FOR RUN TIME 
& LOGIC ERRORS 














DOES IT 
DO WHAT YOU 
WANT IT TO DO? 


No 





Yes 







IS THERE 
MORE YOU NEED TO 
KNOW ABOUT THE 
PROBLEM? 








TEST FOR EXCEPTIONS 
& GET SOMEONE ELSE TO 
TRY IT OUT. 







THIS PROBLEM NEEDS 
A RE-THINK. PUT 

EVERYTHING ELSE ASIDE, 
AND DON'T RUSH 








ERRORS 
2 


No 








WRITE DOCUMENTATIO 
OF HOW IT WORKS, 
FLOWCHARTS 
AND DOCUMENTATION 
OF HOW TO RUN THE 
PROGRAM. 





END 


AN EXAMPLE OF STRUCTURED DESIGN 


5 


2. 


2. 


4. 


Problem Statement 


Write a program that computes and prints the Average or Mean 
(M) and Standard Deviation (S) of a collection of N data items. 
To compute SŠ use the formula: 


Standard Deviation = Sum of Š A of Items) _ (Mean) 


Find out what we have to do (research the problem) 


We are given most of the information in the question but we are 
missing some. It does not tell us how to compute the Mean or 
Average. This is given by the formula: 


(Sum of all numbers) 
Mean = N 


We now have all the information, we need to start designing the 
algorithm. 


What is involved in this problem 


The outline procedure we can now define: 

a) We have to INPUT the numbers, and 

b) Perform two calculations on these numbers. First we calculate 
the Mean and then use the Mean value to calculate the 
Standard Deviation, then 

c) Output the results. 


Design the algorithm 


This gives the detailed procedure for the steps needed to solve the 
problem: 
a) INPUT 
The numbers are going to be input into an array because they 
will be needed twice in the calculation module. 
b) 1. Calculate: the Mean — 
Add all the numbers in the array and divide by N. 
2. Calculate: the Standard Deviation - 
Total the squares of all the numbers in the array. 
Use the formula to calculate S. 
c) Output: the Results — 
The results will be printed on new lines with the words 
MEAN = and STANDARD DEVIATION = 
followed by their values. 


217 


5. The Tree Diagrams 


1. Compute and print 







Standard Deviation 






and mean 


Results 
Each of modules 1.1, 1.2 and 1.3 will be subroutines. These will be 


called in the appropriate sequence by the main program module. 


INPUT 


1.14.2 1.143 


ASK HOW MANY INPUT N NUMBERS 


NUMBERS AND 
INPUT N 


1.1.1.1 

DIMENSION 1.1.3.2 
ARRAY ; FOR I-1 TO N, 
Y(50) INPUT Y(I) 











FIND MEAN AND STANDARD 


DEVIATION 












1.2.4 1.25.34 


^ 
c 







CALCULATE STANDARD 





FIND MEAN 





DEVIATION 


1, 2.1. 2 








SUM ALL DIVIDE SUM BY NUMBER 





ELEMENTS OF ELEMENTS 












FOR I = 1 TO N LET MEAN = 





SUM DIVIDED BY N 





LET SUM = SUM + Ү(І) 


218 


1.2.2. 


CALCULATE STANDARD 
DEVIATION 


1.2.2.1; ls£s2. 2. 
CALCULATE SUM OF USE FORMULA TO 


THE SQUARES CALCULATE STANDARD 
DEVIATION 


ГЕ ТУРУР PI UM PX 

INITIALISE FOR EACH 

VARIABLE ELEMENT GET 
SQUARE, ADD 
TO TOTAL 









LET SUM 






HN FOR I=] SQR-SUM 
TO N SQR«Y(I) 
**? 
( f ON 
SPECTRUM) 











Led 
OUTPUT 
RESULTS 



















lesel 
PRINT "MEAN = "; 
MEAN 


1.3.2 
PRINT "STANDARD 
DEVIATION = '5S 






219 


6. 


The Flowcharts 


The Main Program 


module flowchart: 


GOSUB 
INPUT 
SUBROUTINE 


GOSUB 
PROCESS 
SUBROUTINE 


GOSUB 
OUTPUT 
SUBROUTINE 





220 


The Input Subroutine 
flowchart: 


ENTER 


CREATE 


ARRAY 
Y(50) 









PRINT 
"HOW MANY 
NUMBERS?" 






INPUT 
N 


INPUT 


NUMBER Y(I) 





RETURN 


The Processing 


Subroutine flowchart: 


ENTER 








LET SUM 
= SUM + 





LET SUMSQR 


LET SUMSQR 







ET S=SQR 
(SUMSQR/N) 
( 


- (MEAN**2) ) 


SPECTRUM FORMULA 
USES 7, NOT **, 


RETURN 


222 


The Output 
Subroutine flowchart: 


ENTER 





PRINT 
MEAN 


PRINT 
"STANDARD 
DEVIATION=" 










PRINT 


RETURN 


223 


7. The Program 


ед 


The Мат Program Моаше 


REM "SDEVIATIDN" 

FEM 339 9 3 3 9 ЗЕ ЗЕ ЗЕ C 3 9€ 93639963 
жҰМАТМ FROGRAM MOLD жж 

REM **INFLUT DATA жж 

GOSUE 100 

REM **CALCILATE* 

GOSUE zoo 

REM ##FRINT RESLULTS3* 


BOSE 400 
= TOF 


КЕМ **ENI! MAIN жж 
5 ы ЭЕ ЗЕ ЗЕ ЗЕ ЭЕ 


7.2 The Input Subroutine Module 


95 


100 
110 
120 
130 
140 

SQ 
160 
170 
120 


190 


КЕМ жж А ЗЕ ЭЕ ЭЕ ЭЕ ЖЕ Ж 
X*INFUT SUBROUTINE жж 

DIM Y(S05 

FRINT “HOW MANY NLMEEFRZ?'": 

INFLIT N 

FRINT N 

FOR Ізі ТОМ 

INPUT YLI) 

PRINT ҮСІЗ;" "3 

NEXT I 

RETURN 


REM *#*#END INFUT SUE жж 
аз 


7.3 The Calculation Module 


200 


210 
220 
220 
240 
220 
260 
270 


290 


290) 


300 
210 


—O 


FEM 339 3 € € 3C 9€ 9€ 9€ 9€ 9€ 3€ 303030 3E 3E HE 
XxCOLCULATION SUE жж 
SUM=0 

FOR Ісі ТОМ 

LET SUM=SUM+Y C1) 

NEXT I 

LET MEAN=SUIM/N 

LET СИМЕПК-О0 

ЕПЕ Ісі TON 

LET ФШИМЕОПЕ-СИМФОЕ-һ 
(Y (I) X 2 
NEXT I 

LET $= Sik 
(MEAN жж 
ЕЕТМЕМ 


LET 


[ ^ Spectrum] 


2⁄2 


ССӘПМЕШЕ/М2- 


29) 


FEM **END CALC ‘Sue мен 
JC 3 3C 3C 30 3636 Ж 9C EE EE 


7.4 The Output Module 


400 REM 33939 9c X X 3€ 9€ 3C € 9€ 9€ 3€ EHH 


#*H0UTFUT SUBROUTINE жж 


410 PRINT 


420 


FRINT "МЕАМ-“?МЕАМ 


430 PRINT 


224 


440 PRINT “STANDARD DEVIATION 


450 RETURN 


460 REM **END OUTPUT SUB жж 
333€ CICERO JEDE E EXER ЭН 


8. Documentation 

1) This program will compute and print the Mean and Standard 
Deviation of a collection of data items (numbers). 

2) It allows for a maximum of 50 items to be entered. You can 
increase the size of array Y if you wish to deal with more data. 

3) The numbers can be of any size, positive or negative, to the 
limit of the computer's handling capacity. This is large — you 
will not exceed it. 

4) To run the program key in RUN, and enter numbers one at a 
time, presing NEWLINE (ENTER) after each one has been 
keyed in. 

Sample run to find Mean and Standard Deviation of 30, 31, 
22, 5, бу 7, 30, 12. 22, 3: 
HOW MANY NUMBERS ? 10 
20 31 325 6 7 10113 27 5 
MEAN = 16.4 
STANDARD DEVIATION = 11.45603 
Exercise 


The example program to compute and print the standard deviation of a 
set of data items does not include a pseudocode description of the 
algorithm, and the documentation process is incomplete in other ways 


too. 


i 
2, 


Complete the programming procedure by doing the following: 
Write out a pseudocode description of the algorithm. 
Perform a pre-coding walk through, checking the values of 
the variables, counters and expressions for each subroutine 
module. 

Key in the program and debug it. 

Insert breakpoints in each subroutine and perform a program 
trace. Insert PRINT statements to print out values of 
variables, counters and expressions. 

Obtain a program listing from the printer and run the 
program for a sample set of data. Keep a copy of the printer 
output. 

Document the program fully in your notebook. 


225 


SECTION P: THE CHARACTER SET AND CODES 


Pi: The ZX81 Character Set and Codes 


CODE/CHR$ CODE/CHR$ 
Ü - K] 49 L 
1 F] 50 M 
E ГЛ 51 N 
3 = 52 O 
4 kl 53 P 
5 D 55 r0 
от 55 R 
7 P 56 S 
o B 57 ў 
9 ШЫ 58 U 
uw m 59 V 
11 n 60 W 
12 £ 61 x 
13 $ 62 Y 
14 : 63 2 
15 ? 64 RND 
16 ( 65 INKEY£ 
17 66 PI 
18 67 
19 68 
20 - 69 
21 4 70 
22 = 71 
23 * 79 
24 / 73 
95 74 МОТ 
26 75 USED 
27 | 76 
28 0 77 
29 1 78 
30 2 79 
31 2 80 
32 + 81 
33 5 82 
34 6 83 
35 7 84 
36 8 85 
37 9 86 
38 A 87 
39 B 88 
40) С 89 
41 D 90 
42 E 91 
43 F 99 
44 * 93 
45 H 94 
46 I 95 
47 J 96 
48 K 97 


226 


CODE/CHR$ 


98 

99 
100 
101 
102 
103 
104 
105 
106 
107 
108 
109 
110 
111 
112 
113 
114 
115 
116 
117 
118 
119 
120 
121 
122 
123 
124 
125 
126 
127 
128 
129 
130 
131 
132 
133 
134 
135 
136 
137 
138 
139 
140 
141 
142 
143 
144 
145 
146 


NOT 
USED 


+ Å <> 


GRAPHICS 

EDIT 

NEW LINE (ENTE 
RUBOUT (DELET 
K/L Mode 
FUNCTION 


NOT 
USED 


NUMBER 
CURSOR 


БЕЙБЫТ” лы | ТЫШ 


inverse `` 
Inverse £ 
Inverse $ 
Inverse : 
Inverse ? 
Inverse ( 
inverse ) 
inverse > 


CODE/CHR$ 

147 inverse < 
148 inverse = 
149 inverse + 
150 inverse — 
151 inverse * 
152 inverse / 
153 inverse ; 
154 inverse , 
155 inverse . 
156 inverse 0 
157 inverse 1 
158 inverse 2 
159 inverse 3 
160 inverse 4 
161 inverse 5 
162 inverse 6 
163 inverse 7 
164 inverse 8 
165 inverse 9 
166 inverse À 
167 inverse B 
168 inverse C 
169 inverse D 
170 inverse E 
171 inverse F 
172 inverse G 
173 inverse H 
174 inverse I 
175 inverse J 
176 inverse K 
177 inverse L 
178 inverse M 
179 inverse N 
180 inverse O 
181 inverse P 
182 inverse О 
183 inverse R 
184 inverse S 
185 inverse T 
186 inverse U 
187 inverse V 
188 inverse W 
189 inverse X 
190 inverse Y 
191 inverse Z 
192 тар 

193 АТ 

194 ТАВ 

195 (МОТ USED) 
196 CODE 
197 VAL 

198 LEN 

199 SIN 

200 COS 

201 TAN 


202 


ASN 


CODE/CHR$ 


203 
204 
205 
206 
207 
208 
209 
210 
211 
212 
213 
214 
215 
216 
217 
218 
219 
220 
221 
222 
223 
224 
225 
226 
227 
228 
229 
230 
231 
232 
233 
234 
235 
236 
227 
238 
239 
240 
241 
242 
243 
244 
245 
246 
247 
248 
249 
250 
251 
252 
253 
254 
255 


ACS 
ATN 
LN 
EXP 
INT 
SOR 
SGN 
ABS 
PEEK 
USR 
STR$ 
CHR$ 
NOT 
жж 

OR 
AND 
< = 

> = 

<> 
THEN 
TO 
STEP 
LPRINT 
LLIST 
STOP 
SLOW 
FAST 
NEW 
SCROLL 
CONT 
DIM 
REM 
FOR 
GOTO 
GOSUB 
INPUT 
LOAD 
LIST 
LET 
PAUSE 
NEXT 
PI 
PRINT 
PLOT 
RUN 
SAVE 
RAND 
IF 
CLS 
UNPLOT 
CLEAR 
RETURN 
COPY 


Of the non-printing characters, those that are used, but print a question 
mark, are the following: 


116-121 inclusive 
126-127 Inclusive 


(NOTE: 5 1s the question mark.) 

192 is the Quote image character, which prints a single quote. The 
character set is coded with the numbers 0 to 255. This, you may recall, 
is the number of values held in a single byte. The characters can thus 
be accessed with a single byte identification code. This is also the 
reason why some codes are listed, but have no character associated 
with them. The same is true of the Spectrum character set, which 
follows. 


P2: Spectrum Character Set and Codes 


Code Character Code Character Code Character 
0 35 ж 70 Е 
1 36 $ 71 G 
2 37 % 72 H 
3 not used 38 & 73 I 
4 39 | 74 Ј 
5 40 ( 75 K 
6 PRINT comma 41 ) 76 ІР 
7 EDIT 42 it M 
8 cursor left 43 + 78 N 
9 cursor right +} ; 79 О 

10 cursor down 45 — (minus sign) 80 P 
11 cursor up 46 ; 81 о 
19 DELETE 47 / 82 R 
13 ENTER 48 0 83 5 
14 number 49 1 84 d 
15 not used 50 2 85 U 
16 INK control 51 3 86 V 
17 PAPER control 52 4 87 W 
18 FLASH control 53 5 88 x 
19 BRIGHT control 54 6 89 Y 
20 INVERSE control 55 7 90 Ж 
21 OVER control 56 8 91 [ 
22 AT control 57 9 92 / 
23 TAB control 58 : 93 ] 
24 59 š 94 f 
25 60 < 95 aa 
26 61 = 96 £ 
27 not used 62 > 97 a 
28 63 ? 98 b 
29 64 @ 99 C 
30 65 A 100 d 
31 66 B 101 e 
52 space 67 C 102 f 
33 ! 68 D 103 g 
34 69 Е 104 h 


228 


Code Character Code Character 


105 i 159 (p) 213 MERGE 
106 j 160 (q) 214 VERIFY 
107 k 161 (r) 215 BEEP 
108 l 162 (s) 216 CIRCLE 
109 m 163 (t) 217 INK 

110 n 164 (u) 218 PAPER 
111 о 165 RND 219 FLASH 
112 p 166 INKEY$ 220 BRIGHT 
113 q 167 PI 221 INVERSE 
114 r 168 FN 222 OVER 
115 S 169 POINT 223 OUT 

116 t 170 SCREENS 994 LPRINT 
117 u 171 ATTR 295 LLIST 
118 у 172 АТ 226 STOP 
119 w 173 TAB 227 READ 
120 x 174 VAL$ 228 DATA 
121 y 175 CODE 229 RESTORE 
122 2 176 VAL 230 NEW 

123 { 177 LEN 231 BORDER 
124 | 178 SIN 232 CONTINUE 
125 } 179 COS 233 DIM 

126 ~ 180 TAN 234 REM 

127 © 181 ASN 235 FOR 

128 т 182 ACS 236 GO TO 
129 а 183 ATN 237 GO SUB 
130 P| 184 LN 238 INPUT 
131 = 185 EXP 239 LOAD 
132 n 186 INT 240 LIST 

133 e 187 SOR 241 LET 

134 a, 188 SGN 242 PAUSE 
155 ШТ 189 ABS 243 NEXT 
136 m 190 PEEK 244 POKE 
137 =" 191 IN 245 PRINT 
138 B 192 USR 246 PLOT 
139 p 193 STR$ 247 RUN 

140 == 194 CHR$ 248 SAVE 
141 all 195 NOT 249 RANDOMIZE 
142 L. 196 BIN 250 IF 

143 Kj 197 OR 251 CLS 

144 (a) 198 AND 252 DRAW 
145 (b) 199 = 253 CLEAR 
146 (c) 200 = 254 RETURN 
147 (d) 201 <> 255 COPY 
148 (e) 202 LINE 

149 (0) 203 THEN 

150 (g) 204 ТО 

151 (Һ) 205 STEP 

152 (i) 206 DEF FN 

153 (j) 207 CAT 

154 (k) { user 208 FORMAT 

155 (1) ( graphics 209 MOVE 

156 (m) 210 ERASE 

157 (n) 211 OPEN # 

158 (o) 212 OPEN # 


229 


There is an important point to be noted with regard to the Spectrum 
character set, which does not apply to the ZX81. Among the Spectrum 
character set, codes 16 to 23 are control characters which are 
used to specify certain attributes of the character cell for printing 
purposes. These require arguments within a certain range (0 to 9 for 
colours, or 0 and 1 for on or off, etc.). Codes 6 to 14, 22 and 23 are also 
control characters for printing and editing. The problem with using 
CHR$ with these control characters is that they can be used in 
programs, and are then called by inserting, e.g. CHR$ 20, followed by 
the argument. This means that a simple call to PRINT one of these 
CHRS will cause the computer to think it is being given an instruction, 
and the syntax demands an argument. If this is not forthcoming after 
the CHR$, or the argument is in the wrong range, an error message 
results when the Spectrum cannot do what it thinks it is being asked to 
do. 

Some of these control characters, however, for colour (dealt with in 
Section W), and also for print control can be usefully placed in 
programs. If we take CODE 8, which is a cursor control character, we can 
write a program like this: 


10 PRINT ‘‘SIN”’; 
20 PAUSE 50 
30 PRINT CHR$ 8;CHR$ 8; “АСКЕПр” 


The CHRS 8 instructions in line 30 backspace the cursor twice, re- 
setting the PRINT position, so that “АСКЕР” overprints “ТМ”, The 
upshot of this is that we cannot print out the character set of the 
Spectrum completely, but must start from CODE 24, after the control 
characters. This is no great loss, since they print (or would print, if you 
could get them to!) either a space or a question mark. Remember these 
control characters, though, as they can sometimes be useful in a 
program, although mostly it is far more convenient to use the BASIC 
instructions. For example, we can use CHR$ 23 instead of TAB: 


10 PRINT CHR$ 23;10; “ТАВ CONTROL" 


This is not an advantage over using TAB! However it does show how 
these characters are used by the computer- it inserts them into 
program listings where the control function (e.g. T'AB), has been used. 
TAB itself does not have a control function, and needs CHR$ 23 placed 


after it to work. 
P3: Characters 


The ZX81 and Spectrum have a character alphabet consisting 
of 256 items which include numeric characters, alphabetic 
characters, keywords, instructions, commands, operators, 
graphics and inverse graphics symbols and other symbols. As 


230 


seen in the tables in the previous Units, of these 256 items 
some are not used at all, and some are non-printing (i.e. 
control characters). 

In Appendix III the ZX81 character codes are laid out by 
character type and their position on the keyboard. Spectrum 
codes are referenced alphabetically in Unit W1. 

The CODE (occupying a single byte) identifies each 
character uniquely for input/output purposes – i.e. input 
from the keyboard and output to the screen or printer. 


The ZX81 has a non-standard character set unique to the machine. 
The Spectrum has a character set in which the characters used have the 
codes of the ASCII character set (an internationally agreed standard) 
for the most part. Non-standard ASCII characters are the symbols for 
£ and ©, and the graphics characters. 


Р4: CHR$ and Code 


The purpose of the instructions CODE and CHR is to convert from 
the code to the character and vice versa. The ZX81 and Spectrum have 
different character sets and codes, but the instructions work in the 
same way. 


CODE 


CODE is a function that takes a character or string and gives 
as a result the numeric code that the character (a single 
letter string, or first character in a string) cor- 
responds to. For example: 

CODE S gives 56 on the ZX81, 83 on the Spectrum 

CODE “ABCD” gives CODE А, 38 on the ZX81, 65 on the 

Spectrum 

CODE X$ gives the code of the first (or only) character 

in X$ 

CODE D$(3) gives the code of the third character in D$. 


CHR$ 


CHR$ (N), where N is a numeric expression with a value 
0 < = N < = 255, is a function that gives as a result the single 
character whose code is N. CHR$ does the opposite of CODE. 
For example: 


CHRS (A + B + C) 

CHRS$ (X/Z) 

CHR$ (INT(RND * 255)) 

CHR$ 36 gives 8 on the ZX81, $ on the Spectrum 


231 








To see the inverse relationship of CHR$ and CODE, key in the 
following as direct commands: 


PRINT CHR$ 50 will print M on the ZX81, 2 on the 
Spectrum 

PRIN T CODE 52" ° will print 30 on the ZX81, 50 on the 
Spectrum 

PRINT CODE CHR$ 50 will print 50 

PRINT CODE “A” will print 38 on the ZX81, 65 on the 
Spectrum 

PRINT CHR$ 38 will print A on the ZX81, & on the 
Spectrum 


PRINT CHR$ CODE “А” will print A 


The next program will print out all the characters used on the ZX81. 


10 FOR Е=0 TO 255 
20 SCROLL 
20 PRINT Е, CHR F 
40 NEXT F 


For the Spectrum, as noted above, we must miss out some CHR$ and 


line 20. Line 10 must read FOR F = 24 TO 255. Key it in and run it. 
Add: 


3:9 LPRINT F; TAE à: CHF F 


to get a printer listing. A better program (since it uses less printer 
paper!) but one with an expression you won't understand until we 
cover logic, is this one: 


10 REM ##CHARACTER ЕТЖ 
20 LFRINT "CODE/CHE$": TAB 10; 
"CODE/ICHR$":; TAB zZO:"CODE/CHRE$" 
30 FOR Е=0 To 85 
40 LFRINT F? ТАЕ 4; CHES F; 
ТАБ 10;F+sé; TAE 14; CHES$ 
CF+ie); ТАЕ 20% (F+172 AND 
F+172<25693; TAE 24; CHES 
(F+17Z AND Е+172<256) 
ou NEXT F 


Use these lines for the Spectrum version: 


20 FOR Ғ-24 To 77 

40 LPEINT F; TAE 4; CHES F; 
TAE 10:F*77: ТАР 14: CHES 

(Е%773; TAB 20:Е+154; TAE 24: 
CHES (F+154) 


Exercises 


1 Key in and run the following programs. You may find some 
surprising results, due to the control characters, on the 


232 


Spectrum. No harm will be done. 


(a) 10 FOR F = 0 TO 255 (Spectrum: FOR Е = 24 ТО 255) 
20 PRINT CHRS F; 
30 NEXT F 
Notice that the word characters print with the spaces that 
your computer automatically inserts in program lines. 


(b 10 RAND 
20 PRINT CHR$ INT (128* RND + 128) 
30 GOTO 20 


(c) 10 INPUT A$ 
20 PRINT A$, CODE A$ 
30 GOTO 10 


(d) 10 PRINT “INPUT STRING OF 6 CHARACTERS" 
20 INPUT A$ 
30 FOR F =1 TO 6 
40 PRINT A$(F), CODE АЖЕ) 
50 NEXT F 


(e) 10 RAND 
20IF INT (RND*2)=1 THEN PRINT CHR$ INT 
(RND*128) 
30 IF INT (RND*2)-0 THEN PRINT CHR$ 
(INT(RND*128) + 128) 
40 GOTO 20 


(f 10 RAND 

20 LET A$ = CHR$ INT (RND* 255) 

30 SCROLL 

40 PRINT CODE A$, A$ 

50 GOTO 20 
In this last program, Spectrum owners can omit line 30 and 
simply respond to the Scroll? prompt by pressing ENTER. 
Write a program that given a number (code), will check that 
0 < = code < = 255, and will print out the character. On the 
Spectrum, the program should print “CONTROL 
CHARACTER” if the CODE is between 6 and 23. 
Write a program that when given an alphabetic character as an 
input will print out the next in the alphabet. If the character 
input was ‘Z’ then ‘A’ should be printed. 


SECTION О: GRAPHICS 
Q1: More Printing 


Since we dealt with the PRINT instructions, you have been introduced 
to other statements that can be used with the PRINT statements for 
format and manipulation. 

Loops are of use in printing. For instance we can set up an empty 
string with 32 spaces and use it to clear different areas: 


20 LET A$ = ‘‘(32 врасев)” 
ЖІТІ 

ӘЛГІ 

100 FOR Х-11 ТО 21 

110 PRINT АТ X, 0; A$ 
120 NEXT X 


will clear the bottom half of the screen, and we could use it repeatedly, 
as a subroutine, if we wished. We then avoid using CLS, which would 
mean re-printing anything that we wanted to keep on the screen. 

Except for numbers, anything we wish to print must be in the form 
of a string, either between quotes, a string variable, part of a string 
array, or a CHR$(X) instruction. 

Obviously any operations or functions used with strings may be 
useful, and in the same way as: 


10 PRINT (1 + 3) 
prints 4, we can use: 

20 PRINT A$ (X TO Y) 
to extract the desired characters of A$. 


Enter and run this program 


10 LET A$-"ABRACADAEEA" 

20 LET L= LEN ñ$ 

30 FOR X=1 TO 6 

40 PRINT TAE 10+X;ASCX ТО 
Lela}? 

20 NEXT X 


Remember that numbers can always be treated as strings, and vice 
versa, using VAL and STR$. This is often useful for formatting 


numbers. For example, with a number X, this program: 


234 


10 LET A$="0000" 

20 LET BS= STRS X 

ЗО FOR F-1 Tü 4 

40 IF LEN B$4F THEN GOTO 70 
20 LET A$(CFD-E$CF? 

&O NEXT F 

70 PRINT A$ 


will print (һе first four digits of any number, ог follow (һе number with 
zeros if less than 4 digits. Change the zeros to spaces, and you have a 
number string that will overprint any other string however many digits 
are in the original. 

Code the program in with A$ = (4 spaces)’ and try it. As it is, you 
wil have to enter X as a direct command (LET Х= 123, then 
NEWLINE/ENTER) and then use GOTO 10, since RUN would 
clear the variables (in this case, the value of X you have just entered). 

This principle can be expanded. Here is an example of a subroutine 
used to justify numbers and print them in the position required for the 
decimal places to be in the same column: 


10 REM "FORMAT" 

20 REM *FORMAT SUBROUTINE For 
*NUMEERS ж 

30 REM #COLUMN NUMBER ЕСЕ + 
*#DECTMAL РАСЕ + 


40 LET t=12 

S0 REM *INITIALISE GOSUB* 
ео LET ҒОЕМАТ-УООО 

70 REM *NUMBER* 

во INPUT М1 

7O REM #*#INITIALIZE NUMEER* 
100 LET N=N1 

110 GOSUE FORMAT 

200 REM *MORE NUMBERS + 

210 FOR ісі TQ 4 

220 INFUT N 

220 GOSWE FORMAT 
240 NEXT L 


2020 GOTO 999 


2770 REM HHH EEE 
Xe SIE ROUT INE жж 


7000 LET N$- STF$ М 

9010 LET Р=0 

7020 FOR F=1 TO LEN МФ 

ЭО20 IF МФ(ҒО-"." THEN LET F-F 
7040 NEXT F 

2050 IF F=1 THEN LET N$="O"+N% 
7060 LET F=F+(P=1) 

7070 IF F=0 THEN LET F= LEN N$+1 
7020 FRINT TAE (C-F+1)7N% 

vOTO FETLIFN 


7100 REM ЖЖЕМПЕПЕ ЕЕ € 3€ 9€ 3€ 9€ 3€ 3€ 
92999. SIUF 


Lines 10 to 240 are a main program to initialise and provide numbers 
for the subroutine. Notice it adds a 0 if the number is a decimal. Line 


235 


9030 sets a marker for a decimal point in the first letter of the number 
string, and adding а 0 is done in line 9050. 9060 uses the logical value of 
(Р = 1) to add 1 if a zero was added, i.e. if P = 1 is true. This will be 
explained in the Section on Logic, but the line is equivalent to IF P = 1 
THEN LET P = 2. Check this by trying both versions of the line. Line 
9070 adjusts the length of the string if there is no decimal place found 
(i.e. if the number was an integer). 9080 prints the number in the 
correct column. 

The next program shows a simple way of tabulating results, using a 


loop: 


10 PRINT “МО.”;ТАВ 4;‘SSOQUARE”’; TAB 12; 
"CUBE -TAB 20“ RECIP” 
20 FOR N=1 TO 10 
30 PRINT N;TAB 4;N*N;TAB 12;N**3; ( 1 on Spectrum) 


TAB 20;1/N 

40 NEXT N 
NO. SQUARE CUBE КЕСІР 
1 1 1 1 
2 4 8 0.5 
3 9 27 0.33333333 
4 16 64 0.25 
3 25 125 0.2 
6 36 216 0.16666667 
4 49 343 0.14285714 
8 64 512 0.125 
9 81 {29 0.11111111 
10 100 1000 0.1 


It is important to remember that numbers are output with 8 figures and 
allow the appropriate space. An alternative is to decide how many 
figures you want and use the INT function. 
For example, we can replace 1/N in line 30 by INT(1E4*(1/N) + 
.5)/1E4 , and get a printout like this: 
NO. SQUARE CUBE КЕСІР 


1 1 1 1 

2 4 8 0.5 

3 9 87 0.3333 
4 16 64 0.25 

5 25 125 0.2 

6 36 216 0.1667 
7 49 343 0.1429 
8 64 212 0.125 

9 81 729 0.1111 
10 100 1000 0.1 


236 


Using the E notation allows easy definition of the number of decimal 
places, without the possibility of missing a zero as, for example, if we 
used INT(10000*(1/N) + .5)/10000, since using 1E4 gives four d.p., 
1E3 three d.p., etc. In using this, be careful with the bracket placing, 
as INT(1E4*(1/N)) + .5/1E4 will not round! Try both the correct and 
Incorrect versions in the program. 

You should note that: 


With PRINT TAB C; or PRINT AT L,C instructions L апа С 
can be dependent or calculated variables. For example: 
PRINT TAB (X*2)/3; 
PRINT AT 10, 20/X; 


Try these: 


10 FOR X=1 TO 5 
20 PRINT AT X, X. * 2:X 
30 NEXT X 


10 FOR X -1 TO 5 
20 PRINT TAB X * 2X 
30 NEXT X 


An automatic INT function operates with PRINT AT 
instructions. 
For PRINT AT (L), (C); if (L) and (C) > nand < n +1, 
(1) and (C) = n 
For example: 
PRINT АТ 3/2, 10.5;°°...”’ 
equals PRINT АТ 1,10;°°...”’ 


Try this: 


10 FOR X - 1 TO 10 
20 PRINT AT X, X/2; X 
30 NEXT X 


The AT function rounds down, exactly as if we had used PRINT AT 
X, INT (X/2); X as line 20. 


PRINT TAB(N), where N is non-integer, rounds to the nearest 
integer. 
TAB N, where N is between X and X + 1, gives TAB X if 
N< X+ .5 and TAB X+ 1 if N2- X + .5. For example 
TAB (1.3) =TAB 1 
TAB (1.5) = TAB 2 


237 


To see the difference, RUN both these programs, use COPY to get a 


printout, and compare the results. 


10 FOR X=0 TO 10 
20 PRINT TAB X/2;:X 
30 NEXT X 


10 FOR Х=0 TO 10 
20 PRINT ТАЕ INT (X/2);X 
30 NEXT X 


You must also watch for arithmetic mistakes in calculating the PRINT 
position. For instance: 


10 FOR X=0 TO 10 
ZO PRINT TAB 20/Х%Х 
20 NEXT X 


is not going to get past line 20 the first time round! Why? 

This next example illustrates the use of PRINT AT to give changing 
display. 

A die is rolled and we wish to display its value for each of a series of 
throws. In addition we require cumulative values after each throw. 
Thus each time line 90 is reached it overprints line 70 and vice versa. 
Similarly line 120 overprints itself after each throw. 


> REM "DICEROLL" 

10 PRINT "NUMBER OF THROWS?" 

го INPUT X 

20 DIM NCE) 

sm CLS 

40 PRINT АТ 2.27 "CUMULATIVE VA 
LUES" 

o0 FRINT АТ 10,47 "1929639639696 
43x d T a жан 

60 FOR M=1 TO X 

é5 PRINT AT 1:3; "THROW"? ТАЕ 1 
4; "VALUE" 

70 PRINT АТ 32107 "ж". "ж" 

SO LET ñ= INT (ёж RND +1) 

20 PRINT АТ 3:103MsA 

100 LET NCA =NCAI+1 

110 FOR Есі TO é 

120 PRINT AT 12:4*E;N(B) 

120 NEXT Б 

140 МЕХТ М 


(М.В. Choose a relatively small value for X (say 24) or the program 
will take a long time to run.) 


238 


Exercises 


1 Modify the FORMAT subroutine to round the number to 3 
decimal places before determining the print position. 

2 Modify your result for the exercise above to print zeros for any 
decimal place not filled. 

3 Write a program that displays the result of throwing three dice, 
displaying the result for each die, and the total value for each 
throw. Overprint the last result with each new one, and store the 
total values resulting. After the specified number of throws, 
derive the average value for a throw. 


Q2: More Plotting 


Although the definition of the graphics on the ZX81 is low, the 
computer has the capacity to draw useful graphs, and most graphics 
processes can be illustrated. This is a program that draws a line 
between two specified points: 


10 INPUT Xl 

20 INPUT Yl 

30 INPUT X2 

40 INPUT Y2 

50 LET X=X(2) -X(1) 

60 LET Y=Y (2) -Y(1) 

65 LET A=(X AND ABS X>=ABS Y) + 

(Y AND ABS X<ABS Y) 

79 LET DX=0 

80 LET DY=0 

90 FOR F=1 TO ABS A 

100 PLOT DX+X(1), DY+Y(1) 
110 LET DX =DS+X/ABS A 

120 LET DY=DY+Y/ABS A 

130 NEXT F 


The logic in line 65 checks which is the greater of the distances to be 
covered between the points, and makes A equal to that, since the 
smaller value will be in a false statement, and will be evaluated as 0. 
You will have to wait until we deal fully with logical operations for the 
explanation of the reason this works. The program library has an 
expanded version of this program (“LINE”). 

Spectrum owners should relish the fact that their machine’s ability to 
accept a simple DRAW X,Y statement makes this entire program 
redundant. Study the principle, however. 

Subroutines can be used for plotting. If you recall our dog-plot, here 
is an example of a subroutine used to fill the screen with dogs. The 
subroutine for this is between lines 300 and 430 and is based on a grid 
(8 horizontal by 5 vertical): 

10 REM "DOGS" 
20 FOR Х-й TO 50 STEP 10 


30 FOR Ү-10 ТО 40 5ТЕР 10 
40 GOSUB 300 


239 


45 NEXT Y 

50 NEXT X 

60 GOTO 700 

300 REM **DOG PLOT** 
310 PLOT Х,Ү 
320 PLOT X+1,Y-1 
330 FOR N=2 TO 4 
340 PLOT X+2,Y-N 
350 NEXT N 
360 PLOT Х+3,Ү-2 
370 PLOT X+4,Y-2 
380 FOR N=1 TO 4 
390 PLOT X45,Y-N 
400 NEXT N 
410 PLOT X46,Y 
420 PLOT X+7,Y-1 
430 RETURN 
700 REM **END** 


With plots of functions where the values of Y are not visible by 
inspection, we can use the computer to ascertain them and derive the 
appropriate scale factor. 


For a function producing positive values of Y, we can use a routine 
as below. We set À and B as the values of X between which we want to 
plot the value of Y, and store the largest number encountered in a 
variable MAXY. The routine is for the ZX81. Spectrum users would 
need to use 240 in place of 60 (line 40), and 160 instead of 40 (line 80). 


10 LET A-CMINIMUM VALUE OF X) 
20 LET B=(MAXIMUM VALUE OF X) 
20 LET МАХҮ=0 

40 FOR Х=А TO Е STEP (Б-А2/60 
SO LET Y=CFUNCTION OF X) 

60 IF Y>MAXY THEN LET MAXY=Y 
70 NEXT X 

SO LET SY=40/MAXY 


Adding the following lines gives us the plot: 


20 FOR X=A-A TO B-A STEP (E-A) 
160 

100 LET YzX*X 

110 PLOT X#é0/(B-AdsY#SY 

120 NEXT X 


Spectrum: 240 not 60 in line 90. 

Notice that all the function values are calculated twice. It would be 
neater to set up either two lists, or a two dimensional numerical array 
(Х(60) and U(60) ог Х(2,60)), and store the values the first time 
round. Try this when we have dealt with numerical arrays. Run the 
program, using different values of X in lines 10 and 20 and some 
different equations in line 5@ (and the same one in line 100). Try 
X**2+3X, X**3 —6X + 2, etc. ( ^in place of ** if using Spectrum). 


Revise the program to allow inputs in lines 10 and 20. 


240 


Q3: Movement and Timing 


We can deal with the two topics of time and motion together. We will 
introduce and illustrate the new functions concerned, and then look at 
them in combination. 

The first new commands (which only apply to the ZX81) are FAST 
and SLOW. If the screen display is to be continuous, the ZX81 has to 
read and print on screen the contents of the display file fifty times a 
second (sixty times a second in the U.S.). It can then only compute in 
the gaps between doing this. Up to now, we have used this continuous 
compute and display mode exclusively. This is SLOW mode on the 
ZX81. The Spectrum works in the equivalent of the ZX81 FAST 


mode, and displays the screen at the same time: 


SLOW allows a continuous screen display. Computations are 
performed in the intervals between reprinting the screen. 
SLOW may be used as a direct command or in a program line. 


FAST blanks out the screen, and the ZX81 computes faster, 
not needing to break off to display the screen. Screen display 
is restored when 
(i) the program ends 

(ii) the program stops to await input 

(iii) the program goes into SLOW mode 

(iv) the program is instructed to PAUSE. 
The screen display is updated during FAST, but only printed 


at a break in the program. 


FAST mode is used whenever it is necessary to perform a large number 
of calculations on the ZX81, and a screen display is not vital. To 
illustrate the two modes, enter and RUN this program: 


10 SLOW 
20 FOR X=1 TO 20 

30 LET Z=X*X**X/X**X 
40 PRINT Z; 

50 NEXT X 


Line 10 is redundant, the ZX81 will already be in SLOW mode. But 
now change it to: 


10 FAST 
and RUN. Change it back and, by counting, see what the difference in 
timing is between the two modes. You can also delete line 10, and shift 


between the modes by using direct commands. Note the flash of the 
screen when you input lines from the keyboard in FAST mode. This 


241 


makes it easy to tell which mode you are in. The ZX81 computer is 
always in SLOW mode at switch on, and if you are shifting between 
the two modes, using direct instructions, then the characteristic flash 
will let you know if FAST is the current mode. 


PAUSE 


PAUSE causes the execution of a program to halt for the time 
specified. The screen display is shown on the screen during 
the PAUSE. Pressing a key during a PAUSE will cut the 
PAUSE short and the program will continue. 

PAUSE N gives a delay of N/50 seconds (N/6@ seconds іп 
the U.S.) 

PAUSE 150 gives a delay of 3 seconds (2% seconds in the 
U.S.) 

If N>32767 the PAUSE will continue until a key is pressed 
on the ZX81. 

If N = 0 the PAUSE will continue until a key is pressed оп 
the Spectrum. 


PAUSE allows us to insert a specific delay in a program. It also allows 
p y prog 
us to cause the program to wait for a key to be pressed before the 
program will continue. The following program illustrates both these 
functions: 
10 PRINT "PROGRAM START" 
20 PAUSE 100 
30 PRINT "2 SECONDS" 
40 PAUSE 100 
50 PRIN'T "4 SECONDS" 
60 PAUSE 200 
70 PRINT "8 SECONDS" 
80 PRIN' "NOW PAUSE UNTIL KEY PRESSED" 
90 PAUSE 40000 
100 PRINT "END" 


Spectrum users must enter line 90 as 90 PAUSE 0. 

PAUSE is useful in programs run in FAST mode on the ZX81, since 
the display file is shown on the screen during a PAUSE, and we can use 
this directly to get a screen display for a specified time. 

PAUSE used the system variable FRAMES to count in units of 
1/50th of a second (1/60th second in the U.S.). This is set by the a.c. 
power supply frequency to the ТУ monitor, which governs the number 
of times a second the screen display is refreshed, which is why the 
timing varies in different countries. 

When a PAUSE commences on the ZX81 the screen ‘flashes’. This 
can be irritating. It can be avoided by use of an empty FOR...NEXT 
loop, which does not produce this effect. The time delay is less precise, 
but for non-timing functions — providing a delay whilst instructions are 
read, for example - it is easily modified to suit. 


242 


10 PRINT "START" 

20 PRINT "2SECOND DELAY" 

30 PAUSE 100 

40 PRINT "FOR...NEXT LOOP" 

50 FOR X = 1 TO 150 

60 NEXT X 

74 PRINT "END" 
The next instruction can be used in a program line by the ZX81 only. 
It does not exist for the Spectrum. The definition and discussion apply 
only the the ZX81, but the method of achieving the same effect on the 
Spectrum is given below. 


SCROLL 
SCROLL moves the whole screen up one line, deleting the top 


line, and sets a new PRINT position at the start of the new 
bottom line. 


To see this work, try this program: 


10 FOR X-1 TO 10 


20 PRINT X 
30 IF X25 THEN SCROLL 
40 NEXT X 


We can use SCROLL to clear printout on the top of the screen, but we 
must remember that if we use SCROLL the print position changes. 
We can, however, use PRINT AT instructions to avoid the bottom line 
print position. Delete line 20 in the above program and insert: 


35 PRINT AT X, 0; X 


Notice that we have to be careful of where we put SCROLL, and when 
we use it. We can use it to prevent a ‘screen full’ error message, but 
unless we want all lines rising from the bottom of the screen we have to 
specify when to use it. 

We can set a line to use SCROLL at the correct place: 


10 FOR X=1 TO 50 


20 PRINT X 
30 IF X>21 THEN SCROLL 
40 NEXTX 


Scrolling on the Spectrum is automatic, the ‘scroll?’ prompt 
appearing when the screen is full. When any key other than BREAK 
and 'N' is pressed, the screen scrolls to display the next screenful of 
information. To get the same effect as is produced by the ZX81 


243 


SCROLL instruction in a program, which can be useful, the procedure 
on the Spectrum is as follows: 
1. The value of — 1 must be POKEd into a system variable at memory 
address 23692. This is done with a program line ‘POKE 23692, - 1’. 
2. Something must be printed on line 21. This can be just a space, or it 
may be the first thing you wish to print in a sequence that will have all 
printing coming up from the bottom of the screen. 
3. Scrolling will then occur, one line at a time, whenever another 
PRINT instruction is given. 

A simple program illustrates this: 


10 POKE 23692, – 1 

20 PRINT AT 21,0:“РКІМТ HERE TO CAUSE SCROLL” 
30 PAUSE 50 

40 PRINT “SCROLL” 

50 PAUSE 50 

60 PRINT “SCROLL AGAIN” 


The PAUSE instructions merely cause а delay to enable you to see the 
process properly. The PRINT item in line 20 could be a space, as long 
as it is something printed on the bottom line. Try this program: 


10 POKE 23692, -1 

20 PRINT AT 21,0;° ” (Single space) 
30 FOR F=1 TO 10 

40 PRINT “РКІМТ” 

30 NEXT F 


We can use SCROLL, or the Spectrum equivalent, to create a moving 
screen display. Try this: 


For the ZX81 For the Spectrum 
10 FOR Х-0 TO 30 STEP .3 10 FOR X =0 TO 30 STEP .3 
20 LET L=15+14*SIN X 20 LET L=15+14*SIN X 
30. PRINT TAB Ls "XX" 30 PRINT TAB L: “ZX.” 
40 IF Х>6.3 THEN SCROLL 40 POKE 23692, – 1 
50 NEXT X 50 NEXT X 


Spectrum users please note also that the POKE instruction will work if 
it is given as line 5 in the program, and line 40 deleted. Try it. 
Try this for a rocket launch: 


‘O PRINT АТ 18:17: "Em 
ZO PRINT s "O" 

30 PRINT ; ПЕШ” 

40 PRINT +" ES: 

90 FOR Гео TO 0 ЕТЕР -1 
60 PRINT АТ ізің" 
79 NEXT С 


244 


SO PRINT "ELASTOFF" 
70 FOR X=1 TO 22 
100 SCROLL 
110 PRINT ж" V" 

_ 129 NEXT X 


Spectrum users need to delete line 100, and insert 85 POKE 
23692, — 1. 

Whilst on the subject of scrolling, here is a routine that scrolls a line 
of text across the screen from left to right. Input a name (inverse 
characters look better), or a line of text, and fill out the line with some 
graphics characters. Lines 20, 50 and 60 fill up the line to 32 characters 
with black squares. The technique can be used with several lines of 
text, but is too slow to be useful if dealing with a full screen: 

= REM *INFUT А NAME* 
*(NICER IN INVERSE) # 
е REM #REPEAT IF LINE NOT 
*FILLEL* 
10 INPUT A$ 
20 IF LEN A$432 THEN GOTO 60 
20 PRINT AT 10:07A% 
40 LET A$=AS( LEN ASI +АФС1 TO 
LEN А%-1) 


20 GOTO 30 

ео LET A$-0$-"H" 

70 HOTE 20 
When you have keyed in the program, try deleting “АТ 10,0,” in line 
30. This gives an effective full-screen display. 


Games programs often utilise interactive graphics, via the INKEY$ 
function. A SKETCH program as below shifts the PRINT position 
around. Note that on the Spectrum, INKEYS$ is not totally reliable. 
Add PAUSE @ to ensure it works. 


10 LET X=10 

20 LET Y=10 

ЗО PRINT RT ҮЧ, "+" 

40 LET X=X-( INKEY$ ="3" AND 
Х>О)+( INKEY$ ="S" AND X<31) 

20 LET Y=Y-( INKEY$ ="7" AND 
Ү>О09%( INKEYS ="6" AND Ү5219 

60 GOTO 30 


This uses logical values to do a multiple operation in lines 40 апа 50, 
which both adds or subtracts 1 to the values of X and Y, and keeps the 
character within the screen limits. This could be done less efficiently by 
the following: 


40 IF INKEY$ = ‘‘5’? AND Х>0 THEN LET X-X-1 
50 IF INKEY$ = “8” AND X<31 THEN LET X-X +1 
60 IF INKEY$ = “7” AND Y20 THEN LET Y-Y-1 
70 IF INKEY$ = ''6" AND Y<21 THEN LET Y=Y+1 
80 GOTO 36 


245 


Im lines 40 to 70 both conditions have to be true to execute the change 
in the values of X or Y. In the original example, these logical tests are 
combined (in the brackets) and use is made of the fact that the 
computer uses 1 for TR UE and 0 for FALSE. These logical values are 
used to change X and Y appropriately, according to which keys are 
pressed, but only if the values of X are within 0 — 31 and the values of 
Y are within 0 — 21 (i.e. within the PRINT AT range). 

If, for example, X is equal to 0, then in line 40 above, the combined 
conditions of INKEY$ = “5” (true, if it is being pressed) AND Х>0 
(not true) will be false. The instruction following THEN will not be 
executed. Similarly, in the line LET X = X - (INKEY$ = “5” AND 
X20)-(INKEY$-2':8" AND X<31) each of the bracketed 
expressions is evaluated for truth/falsity. Only one of the bracketed 
expressions can be true, and if, for example, the first is true, X will 
become X-(1(true)) + (0(false)). Logical operations, which are of 
great importance, are fully covered in Section R. 


We could add: 


35 PRINTATY,X;' ” 


to get a single character rather than a line of characters, but our 
character flickers and is not on the screen very long. 

A better way is to put the values of X and Y into two other variables, 
and use these to store the position where a space is to be printed, 
overprint as late as possible in the loop. 


10 LET X-10 

20 LET Y=10 

30 PRINT AT YsX3"#" 

35 LET А-Ұ 

36 LET Б=х 

40 LET X=X-¢ ІМКЕҮФ ="5" AND 
Х>09%( ІМКЕҮФ z"E" AND X431) 

50 LET ҮшҮ-( INKEY$ ="7" AND 
Ү>024( ІМКЕҮФ ="&" AND Y<21) 

55 PRINT AT AE;" " 

&O GOTO 30 


To get automatic movement, we need to use loops. Try this: 


10 FOR X=25 TO 0 STEP - 1 
20 PRINT AT І1,Х; “ай АТ 12, Хх; Se” 
30 NEXT X 


PAUSE 10 could be inserted as line 25 on the Spectrum to slow things 
down a bit. 

Our car moves, but it leaves bits of itself behind. Add a space after 
each of the print strings, and the trail is automatically wiped out, 
overprinted by the spaces. 


246 


10 FOR X=25 TO 0 STEP - 1 
20 PRINT AT 11,X;“ „Ш "AT 12,X;' щн 
30 NEXT X 


The alternative, which is slower (and harder on the eyes), is to use 
CLS, and reprint the screen. To see the effect, just add: 


29 CLS 


Or try this (which includes, to a rather distorted scale, a gravity effect) 
and imagine you are Galileo: 


1 REM GRAVITY DROP 
10 LET Т-й 
20 LET Н-й 
30 PRINT AT 0,5; "MEN" 
40 PRINT АТ 21,1; "----------- " 
50 IF Н>21 THEN GOTO 110 
60 PRINT AT Н,10; "*" 
70 LET Т=Т+.25 
80 LET H-INT 32*T*T/10 
90 CLS 
100 GOTO 30 
110 PRINT AT 21,7; "*SMASH*" 


The next program utilises graphics to illustrate the principle of the base 
current flow through an NPN transistor. The flow of the main current 
is indicated by a moving black graphic, and the flow of the base current 
by a grey square. Study the program and analyse it so that you can 
follow it. The string manipulation is quite complex. By now Spectrum 
owners should have mastered converting ZX81 programs for their own 
machines. Remember that the values PLOTted on the Spectrum 
should typically be four times larger than on the ZX81 in order to get a 
picture of a similar size. Apart from this, *Transim' should not present 
any problems: 


5 REM "TRANSIM" 

10 PRINT "SIMULATION OF CURREN 
T FLOW ІМ", "+УЕ BIASED NPN TRANS 
ISTOR" 

20 PRINT ss" PRESS 5 TO SWITCH 
OFF BIAZ":"CURRENT FLOW IN BASE" 
119 "PRESS R TO RECONNECT " 

30 PRINT »» "GRAPHICS SHOW ELEC 
TRON FLUOW":,:"HIT A KEY TO START 


40 FALISE 4Е4 

SQ CLS 

во FOR Fz? To 49 

70 PLOT Fo? 

S0 PLOT F512 

90 IF F276 THEN GOTO 120 
100 PLOT 275F*3 

110 PLOT 30,F+3 

120 NEXT F 

130 UNPLOT 29312 


247 


140 UNPLOT 27,12 

150 PRINT АТ 95; "ж NEN TRANSIS 
ТПЕ x": ТАБ Ss "eRe Уы X 
ж! 

160 PRINT АТ 5317: "BASE": AT 7: 
17; "CURRENT ON"? АТ 14,2: "COLLEC 
TOR": TAB 22? “EMITTER 

170 FRINT АТ 5310; ““УЕ"; АТ 18% 
OF +E = Мемма Р Мема -УЕ 

120 REM *w*GFñFHIC STRINGS#* 

170 LET A$-" BEBE BR ELE E ии" 

200 LET $=" TTE E E TTE ы а 
210 LET S$=" ú = mhi" 

220 FOF N=1 TÜ 15 

220 REM **GFñFHICS LOOPxx 
240 FOR Fei TO 8 
Qi IF F=1 THEN FRINT AT 7:14; " 
260 PRINT АТ 16-Ез14: "B" 

270 PRINT АТ 164: B$(F TO Fev; 
ASIF TQ F+iG) 

280 PRINT АТ 7313:5%(1 TO 3); 

270 IF F=f AND ІМКЕҮФ ="S" THEN 

200 PRINT АТ 73143" "b AT 16-F5 
14$ s "H 
310 NEXT F 
320 NEXT М 

330 PRINT АТ 2150; "PROGRAM HALT 
ED. RESTART? CY OR N)" 

340 INPUT ЕФ 

390 IF R$ <> "Y" THEN GOTO 440 

360 PRINT АТ 21:03" 


370 GOTO 220 


95, REM ж Ж А ХЕ Ж 
жжБАСЕ CURRENT OFF СИ!» 

400 PRINT АТ 5:10: “ " АТ 731 
3:5%6(4 ТО); АТ 7:25; "OFF" 

410 IF ІМКЕУ% <> "RE" THEN GOT 
410 

420 FRINT АТ 5310: "+VE"; АТ 731 
2С6С1 TO: 22: АТ 725: "ON * 

430 RETURN 


52 КЕМ ** ENDSUB 339 
HHH 553555555222 


440 CLS 
450 REM **END PROGRAM жж 


Spectrum modifictions: PAUSE @ in line 40. 


The program uses the ‘chunky’ ZX81 plot squares to draw the outline 
(lines 60 to 140). Spectrum plot points could be used, but strings of the 
graphics characters on keys 1 to 8 would be better. Refer to the screen 
diagrams in Unit M2 for the positions on screen requiring printing. 


248 


Exercises 


1. For ZX81 users: Computer performance in terms of speed is 
compared by benchmark tests. Write a program that loops 500 
times, performing a calculation each time. Run it in FAST and 
SLOW modes, and time it. 

2. Revise the left to right scroll to work right to left. 

3. Write a program that draws a ship and moves it backwards and 
forwards across the screen, automatically. 

4. Revise the program to move the ship in response to INKEY$ 
input from the keyboard. 

5. Write a program that uses PAUSE to display minutes and 
seconds. Check the clock against a watch and improve the 
accuracy. 


Q4: The Display File 


In order to talk about the display file, we must introduce some new 
concepts, which are dealt with more fully in a later section of the book 
(Section U). 


The DISPLAY FILE is the memory picture of the screen 
display stored in a sequence of memory locations or addresses 
in the computer RAM. 


BYTE. Each memory location in the computer stores an 8 bit 
(digit) binary number which has a decimal value between 0 


and 255. 


To interact with the computer's memory, we use PEEK and POKE. 
We are concerned here not with the general instructions (which are 
dealt with in Section U) but with some specific uses for these 
commands. We will give a definition of PEEK and POKE here, and 
then discuss the use of these only in terms of some simple techniques 
connected with the screen display that can be of use in graphics. 


PEEK (M) returns the contents of the memory address (M) (a 
binary number) in decimal form. 


POKE (M),(N) inserts the value N (0 to 255) into the 
specified memory address, M. 


The display files of the ZX81 and Spectrum are organised very 
differently. That of the Spectrum is much more complex, due to the 
high-resolution PLOT screen and colour on the machine. We will deal 
with the ZX81 display file in some depth below, and then describe the 
Spectrum display file. Spectrum users should GOTO page 257, and 
omit the ZX81 specific section below, unless they find it interesting for 


249 


general information. It is useful to know the ZX81 display file system if 
you are Interested in converting ZX81 programs for the Spectrum, as 
some programs use the techniques described below. 


On the ZX81: 


Each address of the display file stores in a byte a character 
code, corresponding to the character to be printed on the 
screen. 


The display fille memory location differs according to the program 
length, since it starts where the portion of memory occupied by the 
program ends. For any given program the start location is constant. 


The DISPLAY FILE start address is stored in the system 
variable D-FILE, at memory locations 16396 and 16397. 


For the display fille memory locations: 


PEEK M gives a number (in decimal) which corresponds to 
the character code located in the memory address M. 


POKE puts into one of these memory locations a character 
code. 

POKE M, N puts the number (character code) N into 
memory address M 


The ZX81 has done away with much of the use of POKE in connection 
with the display file, because the PRINT AT function actually uses a 
routine in the computer that finds out where the display file starts and 
then POKEs to it the required characters at the correct position. 

To illustrate the work this saves, here is a program that puts ZX at 
line 1, column 10, on the screen. 


10 LET D = PEEK 16396 + 256*PEEK 16397 
20 LET Z=D+(32+1+11) 

30 -POKE Z, 63 

40 POKE Z+1,61 


Note that, even though we could write the routine above more 
compactly (by missing out line 20 and using POKE D+ 44, POKE 
D +45 as lines 30 and 40) it is still rather more complicated than: 

10 PRINT AT 1,10; TZS? 


Thus we will not use it unless we have good reason. But let’s run 
through what we are doing. Do not worry if you cannot fully 
understand all of this, you can return to this Section later, when the 
memory has been covered. 


250 


Line 10 sets D to the values of the ‘D-FILE’ system variable, which 
stores the memory location of the start of the display file. The address is 
always stored in two bytes (16396 and 16397) of memory and the 
second is the more significant byte (i.e. stores the higher value). Hence 
the *256 before the second memory location. 


PEEK 16396 + 256 * PEEK 16397 returns the value of the 
memory location of the NEWLINE (ENTER) character at the 


start of the display file. 


Line 20 counts along the screen to the position required. The value of 
44 has been broken down to show the principle. The D-FILE address 
contains the NEWLINE (ENTER) character, which is always present 
at the start of the first line. We count 32 for the spaces in line 0, and 
then there is another NEWLINE (ENTER) character, marking the 
end of line 0. We want the eleventh position (column 10) along the 
next line, so we count 11. This gives us a value for the memory location 
corresponding to the desired print position. Using this, line 3@ prints Z 
Бу POKEing the corresponding character code into this location and 
similarly line 4@ puts X in the next position along. 

Notice that the display file has no correspondence to line and column 
numbers, it merely numbers in sequence: 


Start Column Newline (Enter) 

Newline (Enter) Character 
Character 0 1 1 "Dn. 31 

(Line 0) 1 2 з ча 44, 33 34 
jo 36 27 38... 66 67 

MELOS) геу, Ga une ds a 
(ipe 41) c 03) mecs tV VP SEN es {же vd 726 727 
(Line 22) DEC 5052.45 759 760 
(Line 23) Fe Goan CU; 5.22 792 793 


So to use this technique we only need to find the start location of the 
display file once, and allocate a variable to it (D in the program above), 
or arrange to re-use a program line with the PEEK commands. 

To try to make things a little clearer, try the following program: 


10 LET DFILE = PEEK 16396 + 256* 
PEEK 16397 
20 PRINT “DISPLAY FILE START ADDRESS 
І5”, MEMORY LOCATION ”; DFILE 
30 FOR M=DFILE-8 TO DFILE + 8 
40 PRINT M;TAB 10; PEEK M; TAB 18;CHR$ PEEK M 
50 NEXT M 


Line 10 PEEKs the D-FILE memory locations, which store the 
number of the address in which the first NEWLINE (ENTER) 
character of the display file is located. 

If you have entered the program exactly as shown — including the 
space after “Memory Location’’ - line 20 will print: 


DISPLAY FILE START ADDRESS IS 
MEMORY LOCATION 16694 


This is followed by a printout like this: 


16686 118 ? 


16687 0 

16688 50 М 
16689 3 EN 
16690 0 = 
16691 243 NEXT 
16692 50 M 
16693 118 ? 
16694 118 ? 
16695 41 D 
16696 46 Io 
16697 56 S 
16698 53 P 
16699 49 L 
16700 38 A 
16701 62 Y 
16702 0 


This shows a memory address (16686) then the character code it 
contains (118) and its character string (in this case 118 is NEWLINE 
(ENTER), and prints a “?”). Address 16687 is a space (character code 
0) and a space is printed. 16688 contains the number 50, which is the 
line number of the last program line, and prints M. Then there is a 3 
stored (which is the number of characters in the program line) and 
which prints the graphic character, then NEXT (character code 243), 
and M again, this time representing the variable М, not the number 50. 
Then there is a NEWLINE (ENTER) character (118) marking the end 
of the program. The next NEWLINE (ENTER) is at 16694, the start 
of the display file, and then there are the codes and characters for 
DISPLAY (the first words to be printed on the screen). 


To illustrate the use of PEEK and POKE with the display file, here 
is a program to draw on the screen. This does essentially the same 
thing as the sketch program we met earlier, but it uses the technique of 
POKEing characters to the display file directly, instead of via the 
PRINT AT function. We give a full listing here, but in fact to run it, 
you need only enter lines 190 to 290. 


292 


10 
20 


30 


290 
300 


The complex looking line 280 (be careful to input it correctly) uses the 
same logic as was mentioned with the ‘‘Sketch’’ program. If you 
inspect it, after we’ve dealt with logic properly, you will see that each 
key that is pressed gives a different value. The equivalent lines without 


this technique would be: 


280 
281 
282 
283 
284 
285 
286 
287 


REM “ARTIST" 

PRINT “DRAWS A PICTURE BY M 
OVING A CHARACTER IN 8 DIRE 
СТІОМ5" 

PRINT "ТО MOVE IN THE FOLLO 
WING DIRECTIONS PRESS THE C 
ORRESPONDING KEY" 

PRINT TAB 10; "NORTH--W" 
PRINT TAB 10; "SOUTH--X" 
PRINT TAB 10; "EAST--D" 
PRINT TAB 10; "МЕЅТ--А" 
PRINT TAB 10; "NORTHEAST--E" 
PRINT TAB 10; "SOUTHEAST--C" 
PRINT TAB 10; "SOUTHWEST--Z" 
PRINT TAB 10; "NORTHWEST--Q" 
PRINT 

PRINT 

PRINT "TO CHANGE THE CHARAC 
TER PRESS S THEN THE CHARAC 
TER THEN NEWLINE" 

PRINT 

PRINT "DON'T GO OVER THE ED 
GE OF THE SCREEN" 

PAUSE 400 

CLS 

LET T2120 

LET А5-"%" 

POKE PEEK 16396+PEEK 16397* 
256+T,CODE А5 

IF INKEYS="" THEN GOTO 250 
LET BS=INKEYS 

LET T=T+(32 AND B$z"Z")- (33 
AND BS="X")+ (34 AND B$="C" 
)- (34 AND B$z"Q")- (33 AND 
B$="W")- (32 AND В$="Е")+( 

1 AND BS="D")-(1 AND B$=" 
A") 

IF BS="S" THEN INPUT AŠ 
GOTO 246 


ТЕ В5-"2" THEN LET T=T+32 
IF BS="X" THEN LET T=T+33 
IF BS="C" THEN LET T=T+34 
IF В5-"О" THEN LET T-T-34 
IF BS="W" THEN LET T-T-33 
IF BS="E" THEN LET T=T-32 
IF BS="D" THEN LET 'Т=Т+1 

IF В5-"А" THEN LET Т-Т-1 


253 


-33 





-34 32 
= +1 
+32 +34 
+33 
If you look at the diagram above and the numbering of the display file, 
you will see how it works. — 1 or +1 move the position along a line, 


- 34 moves it up one line and to the left etc. All this numbering is 
within the display file. Line 240 PEEKs the D-FILE memory 
locations, adds the display file position number and POKEs into the 
result (a memory address in the display file) the character code for A$. 
Notice the speed of this program. This gives us one reason to use 
PEEK and POKE: to provide speed of display. 

Notice the warning about the edges of the screen in the program 
listing. When you have decided you have played with the program 
enough, try going off the edge of the screen. The results will not harm 
the ZX81, but you will probably have to switch the power off to reset 
the computer. All manipulations of the display file must be done with 
great care so as not to interfere with the NEWLINE (ENTER) 
characters marking the end of each line. If these are altered the 
computer cannot keep track of where everything should be, the display 
will go crazy and the program will crash. Be warned! (And be careful in 
your programming!) 

It is possible to increase the screen size of the display to give the 
capability to PRINT or PRINT AT on the bottom lines of the screen. 
The system variable (DF-SZ) at memory location 16418 holds the 
number of lines in the bottom half of the screen, and is normally set at 
2. If we use POKE 16418,0, the bottom two lines can be used to 
PRINT AT. Try this program. 


10 POKE 16418,0 
20 - POR L = @ TO 23 
30 PRINT “LINE NUMBER” ;L 


40 NEXTL 
50 FOR X =1 TO 300 
60 NEXT X 


Notice that, after the delay caused by the FOR...NEXT loop, the 0/60 
message appears on the bottom line as usual, and that the next 
command from the keyboard clears the bottom two lines. This is 


254 


because DF-SZ returns to its normal value on completion of a 
program. If we use COPY it will also not print the bottom two lines - it 
is only set for a normal screen size of 22 lines. 

We may also restrict the screen size. Key in this program: 


10 POKE 16418, 28 

20 PRINT “TOP LINE" 

30 PRINT “SECOND LINE" 
40 PAUSE 158 

50 PRINT "NOW SCROLL" 
60 FOR Х-1 ТО 4 

70 SCROLL 

80 PRINT "SCROLLED ";X 
90 МЕХТ Х 


The SCROLL instruction now operates from the bottom line of a 
screen which is only 4 lines deep. This can be used to clear just the top 
part of the screen, leaving the rest undisturbed. 

Try this next program, which uses both these techniques together. 
(You don’t need to input the text in lines 70, 90 and 110. Just PRINT 
1, 2 and 3 instead). 

10 POKE 16418,0 


20 FOR L=0 ТО 23 
30 PRINT "LINE NUMBER ";L 


40 NEXT L 
50 POKE 16418,21 
60 SCROLL 
76 PRINT "THESE LINES" 
80 SCROLL 
90 PRINT "NOW CLEARED AND " 
100 SCROLL 
110 PRINT "REST OF SCREEN LEFT 
AS IS" 
120 FOR Х-1 TO 300 
NEXT X 


If entered as above, the top portion of the screen would look like this: 


THESE LINES NOW 
CLEARED AND REST OF 
SCREEN LEFT AS IS 
LINE NUMBER 3 

LINE NUMBER 4 

LINE NUMBER 5 

LINE NUMBER 6 


Unfortunately, we cannot choose a screen section in the middle of the 
screen (e.g. lines 6, 7 and 8) to do this with, and must use PRINT AT 
“(32 spaces)’’ with the lines we want to clear, or overprint directly, or 
POKE spaces into the relevant positions, as in this program: 

10 FOR F= 1 TO 9 

20 PRINT "LINE NUMBER ";F;" 


(16 SPACES) END" 
30 NEXT F 


255 


40 PRINT "LINE NUMBER TO BE 
CLEARED ?" 

50 INPUT LINE 

60 LET DFILE-PEEK 16396+256*PE 
EK 16397 

70 FOR X-1 TO 32 

80 POKE (LINE-1) *33+DFILE+X,9 

90 NEXT X 


Note that if we put: 
70 FOR X=32TO1STEP -1 
we get a reverse line clearance (right to left), and 
70 FOR X=32 TO 30 STEP - 1 


clears END, but leaves the rest of the line. 

Another useful system variable concerned with the ZX81 display file 
is the DF-CC address, locations 16398 and 16399. This holds the 
address of the current print position in the display file. If this address is 
found by using PEEK 16398 + 256* PEEK 16399 then it can in turn be 
PEEKed, and will give the code of the character present at the current 
print position. Note that the current print position is the next position to 
be printed. A line like 


10 PRINT TAB8; “А” 


leaves the current print position set at the start of the next line of the 
display, and 


19 PRINT TAB 8; A": 


gives as the current print position the next position after the A. To 
illustrate, here is a variation on the basic screen movement program we 


derived from SKETCH which uses the DF-CC variable. 


10 LET Х-10 

20 LET Ү-10 

30 PRINT АТ Ү,Х; 

40 LET D=PEEK 16398%256%РЕЕК 16399 

50 PRINT "*" 

60 LET Х-Х-(ІМКЕҮ%-"5" AND X>@) 
+ (INKEYS="8" AND X<31) 

70 LET Ү-Ү-(ІМКЕҮ5-"7" AND Y>@) 
+ (INKEYS="6" AND Y«21) 

80 POKE D, @ 

90 GOTO 30 


Instead of setting two variables as equal to X and Y before their values 
are altered (before line 50) in order to identify where to print the space 
which blanks the ‘‘*’’, we use variable D to store the location of the 
print position (line 40) and then POKE a 0 (space) into it to overprint 
(line 80). 


256 


Notice lines 30 and 40. We must set the PRINT AT position in line 
30, then PEEK the DF-CC addresses, then PRINT the ‘‘*’’. 

The ASTEROIDS program in the program library uses the 
technique of PEEKing the next PRINT position to determine whether 
a black square occupies this position. The relevant lines are 


130 PRINT AT 5,C; 

140 IF PEEK (PEEK 16398 + 256*PEEK 
16399) = 128 THEN GOTO 250 

150. PRINT 44” 


Look up the program апа work out how these lines relate (о the rest of 
the program. If you find line 140 confusing, remember that the ZX81 
evaluates expressions in brackets first. It gets the value stored in the 
16398/9 addresses, which returns the address of the PRINT position, 
then PEEKs this address. 

We will now deal with the Spectrum display file, which does not 
have the straightforward structure of that of the ZX81, and to which 
PEEK and POKE techniques have little application. 


SPECTRUM DISPLAY FILE 


The Spectrum display file is organised in a very different way to that of 
the ZX81. This is a consequence of the high-resolution screen display 
on the Spectrum (256 * 176 points are plotable), compared to the 
‘chunky’ graphics of the ZX81, with only 64 * 44 plot squares. The 
pattern of squares in any character cell on the ZX81 can be defined as a 
character code. On the Spectrum each individual point of the 8 by 8 
grid of a character cell must be individually specified. 

The Spectrum display file is fixed in memory, and does not vary its 
location. There is no need to PEEK a system variable to find its 
position, as the start address is always 16384, and it is a fixed length of 
6144 bytes, occupying the memory addresses up to 22527. 

The complex method of organisation means that it is not possible (as 
it is with the ZX81 and other computers), to POKE character codes to 
the screen and have the character specified by that code appear. 
Similarly, we cannot PEEK the screen to find out what character, if 
any, occupies a given location. Both these operations are theoretically 
possible, with much calculation, but not practicable. However, the 
speed of the Spectrum’s operations takes away much of the advantage 
of using PEEK and POKE on the ZX81, and we can use PRINT AT 
instructions to place characters on the screen, and two special 
Spectrum functions for finding out what is on the screen. Before 
introducing these instructions, here is a description of the way the 
Spectrum display file is organised: 

Each character cell has an 8 by 8 dot matrix of points, which may be 
‘set’ (blacked or inked in) or not. These patterns of dots make up the 


257 


characters. We'll treat this in more detail later. For plotting, each point 
must be specified individually, and this means that the characters 
available in the character set do not cover the whole set of possibilities 
for each cell. To cope with this, the Spectrum stores each pattern of 
points along a 32 character cell line on the screen in a sequence of 
bytes. However, these are not stored in sequence down the screen. The 
top point sequence of each of the first eight rows of characters (lines) 
are stored one after the other. The second line of points in each of these 
8 lines of characters is then stored, and so on until the first eight lines of 
the screen display have been defined. The next eight lines on the screen 
are then stored in the same way, followed by the bottom eight lines of 
the 24 line screen. 
To make this clearer, key in the following program and run it: 


10 FOR A= 16384 TO 22527 
20 POKE A, 85 
30 NEXT A 


This puts into each byte the binary form of 85 (01010101), giving 
alternate plotted and unplotted (‘set’ and ‘unset’) points. You will see 
that the top line of points for each of the top eight lines on the screen 
appears, in sequence top to bottom, then the second line of points for 
each of these eight PRINT lines, and so on. When this sequence has 
finished, it repeats for the next block of eight lines, and then again for 
the bottom eight. 

You should now see why it is not easy to define a particular sequence 
of POKEs to the display file to get a character on screen! This is best 
done using PRINT AT on the Spectrum in all cases. Pixels can also be 
plotted, of course, and in Section W the user-defined graphics available 
on the Spectrum are dealt with, which enables any character cell 
pattern of 8*8 plot points to be defined and treated as a character which 
can be placed on the screen with a PRINT AT instruction. 

To find out what is on the screen at a particular place we use 


SCREENS (instead of PEEKing the display Ше) on the Spectrum. 


SCREENS 


SCREENS is a Spectrum specific function. It returns the 
single-character string of the character printed at the specified 
line and column co-ordinates. It has the form: 
SCREENS (L,C) 
PRINT SCREENS (2, 6) returns the character printed at Line 
2, Column 6 on the screen. The brackets cannot be omitted. 
SCREENS will return the true video form of any inverse 
character. It does not recognise either the true video or 
inverse video forms of the Graphics characters. 


250 


Note the restriction on what SCREENS will recognise. The chunky 
graphics characters on keys 1 to 8 are not recognised. An empty string is 
returned. Run the following program to see SCREENS$ in action. After 
you've tried other characters, try the graphics characters and inverse 
video. Input PRINT LEN SCREEN$(10,10) as a direct command to 


see that the null string (no characters) is returned. 


10 INPUT A$ 
20 PRINT AT 10, 10; A$ 
30 PRINT SCREENS (10,10) 


There is another Spectrum specific instruction that can be used to find 
out what is currently on the screen. This is POINT. 


POINT 


POINT returns 1 if a specified PLOT pixel is inked in (‘set’), 
Ø if it is not. It has the form 

POINT (X,Y) 
where X and Y are the PLOT screen co-ordinates of the point 
to be checked. 


To see the action of POINT to check if a plot pixel has been inked in, 
key in the following: 


10 PLOT 128,88 
20 PRINT POINT (128,88) 
30 PRINT POINT (128,89) 


POINT returns 1 for line 20 (pixel plotted), and 0 for line 30 (pixel not 
plotted, or ‘unset’). Notice that the brackets must be placed around the 
X and Y expressions. Both POINT and SCREENS will, of course, 
work with calculated values. POINT can be used to give information 
about inverse characters that SCREENS will not provide. We can 
illustrate this simply. Key in this program: 


10 PRINT “EP 

20 PRINT POINT (0,175) 
30 PRINT AT 10,10; Ml" 
40 PLOT OVER 1;84,90 
50 PRINT POINT (84,90) 
60 PRINT POINT (85,90) 


Line 20 checks the upper left corner pixel of the character cell with the 
exponentiation sign printed in inverse video. This returns 1, since the 


pixel is set. Line 30 prints an inverse square (CAPS SHIFTed graphic 


259 


8), which SCREENS will not recognise. Line 40 unplots 1 pixel, using 
the OVER 1 statement, and line 50 checks this plot point, returning 0, 
since it is unplotted, and line 60 checks roughly the centre point of the 
black square, which returns 1. This offers us a way of checking inverse 
characters. You must, of course, make the correct calculations for the 
transfer from the PRINT to PLOT screens. 

You should notice two points for future use, after Section W has 
introduced the other Spectrum functions not dealt with in the main 
body of the text. One is that we referred to POINT returning 1 if the 
pixel was set or inked in, and when you start using colour, you should 
remember that POINT checks for the currently specified INK colour. 
For our purposes, this is black. The other is that the colour attributes 
that refer to a character cell when colour is used can be another source 
of information about the screen display. (This uses the ATTR 
function. See Unit W3.) 


260 


SECTION R: LOGICAL OPERATIONS 


R1: Logic Values and Numeric Values 


When using the logical capability of Sinclair BASIC we must 
distinguish between logical values and the numeric values produced by 
logical evaluation. We have touched upon this earlier in the book, but 
deferred a full explanation until now. 
LOGICAL VALUE is the value of an expression using the criteria: 
any non-zero value of the expression = ‘‘TRUE”’ 
a zero value of the expression = ‘‘FALSE”’ 
When an expression is logically evaluated it is assigned one of two 
numeric values: 


“TRUE” 1 
“FALSE” 0 


R2: Boolean Operators: The AND Operator 


AND A 
Examples 100 IF (A = 10) AND (B<>3) THEN GOTO 60 
200 PRINT (A AND B) 


The AND operator (symbol ^ ) forms a logical conjunction between 
two expressions involving conditional operators. 

If both expressions are ‘‘TRUE”’ the conjunction is “ТЕСЕ”. 

If one or both are ‘‘FALSE”’ the conjunction is ‘‘FALSE?’’. 

The numeric value of “TRUE” is 1. 

The numeric value of “FALSE” is 0. 

All non-zero values аге “ТЕСЕ”, 

In line 100, if the relation A = 10 is “ТЕГЕ” and the relation B<>3 
15 “TRUE” then control will pass to line 60. If either or both of the 
relations is ‘‘FALSE”’’ then control passes to the next line. 

In line 200 the computer will not print A + B. It will print the value of 
A or 0 depending on the values of A and В. 

Remember: All non-zero values are “TRUE”. 


So if 
A = 15 and B = 6 
A = “ТЕСЕ” B = “TRUE” 


So the relation (A AND B) is (“ТКСЕ” AND “ТКСЕ”). 

So the result is logically “TR UE”. 

15 is printed. 

If A = 16 (“TRUE”) and В = 0 (zero value – logically 
“FALSE’’). 

Then (A AND B) is ((TRUE" AND ‘‘FALSE”’’) =“ FALSE” = 0. 

So @ is printed. 


We will explain this in more detail later. 


261 


Truth Table for AND 


A | > [sees 
| TRUE | 


A 
TRUE 


A and B are conditional expressions. 








R3: The OR Operator 


OR V 
Examples 100 IF (A>1) OR (B = 0) THEN STOP 
200 PRINT (C OR D) 


The Boolean operator OR (symbol v ) forms the logical disjunction of 
two expressions involving conditional operations. 


If either or both of the expressions is “TR UE” the OR disjunction is 
"IRUE'". 
If both expressions are ''FALSE"'' the OR disjunction is ‘‘FALSE’’. 
In line 100 if either of the expressions (A21) and (B = 0) аге 
“TRUE” the program will STOP. 
If both are **FALSE'' control passes to the next line. 
In line 200 if C2 10 = '"TRUE'" and D= 0 = "FALSE" 
С OR D=“TRUE” OR “FALSE” = ““TRUE”’ 
10, the value of C is printed. 
If C=@ = “FALSE” and D = 0 = “FALSE” 
C OR D= “FALSE” OR “FALSE” = “FALSE” 
So @ is printed. 


Truth Table for OR 


TRUE TRUE TRUE 
TRUE FALSE TRUE 
FALSE TRUE TRUE 
FALSE FALSE FALSE 


A and B are conditional expressions. 










R4: The NOT Operator 


NOT `] 
Examples 20 IF NOT A THEN STOP 
30 IF NOT (A = B) THEN STOP 
100 PRINT NOT A 


262 


NOT (symbol | ) logically evaluates the complement (reverse) of a 
given expression. 

In line 20, if A210 then A=‘‘TRUE”’ апа NOT А = NOT 
“TRUE” = “FALSE”. 

So in line 20 if A is 10, NOT A is “FALSE” and control passes to 


the next line. 

IfA=@ ("FALSE') then NOT A= NOT “FALSE” “ТЕСЕ” 
and the program stops. 

In line 30 if (A= B) is “FALSE”, NOT (А = В) = NOT “FALSE” 
= “ТКСЕ”, so program stops. 

In line 100 1А = 0 = ‘‘FALSE”’ then NOT А = “TRUE” = 1 


So 1 is printed. 
If A= 29 then A is “ТКГПГЕ” and NOT А = ‘‘FALSE’’, and 0 is 


printed. 


Truth table for NOT 


TRUE FALSE 
FALSE TRUE 


A is a conditional expression. 






R5: Conditional Operators 


‘There are two ways to use conditional operators in logical evaluations. 
1. ‘To check the numeric value of an expression 





Examples 100 IF A= 3 THEN GOTO 60 
200 IF B<>C THEN STOP 


The numeric value produced by the logical operation is not important. 
We are concerned only with the truth or falsity of the condition 
indicated іп the IF... THEN statement, which determines whether the 
instruction is executed. When the specified condition is present 
("TRUE"), the statement after THEN will be carried out. 


2. То check on the numeric value produced by logically evaluating ап 


expression 
In this case we want the numeric values, where ‘“TRUE’’=1 and 


"FALSE' = 0 


Examples 200 PRINT A<B 
300 PRINT A=3 


The PRINT statement used as above will give the numeric values 


produced by logical evaluation. 
Line 200 is evaluated as a logical expression, so that if it is TRUE 


263 


that A is less than B, 1 will be printed, and if A is equal to or bigger 
than В, the expression is false and 0 will be printed. 

Line 300 is interpreted by the BASIC as: “Print 1 if = 3, 0 if A 
does not equal 3.” 

The numeric value of the logical evaluation is distinct from the 
logical value of the expression. 


R6: Logic Operations on Conditional Expressions 


IF (CONDITION AND| CONDITION) THEN... 

IF (CONDITION) THEN... 
The effect of the logical operators AND, OR and NOT on 
conditions which are TRUE or FALSE gives a result which is 
TRUE or FALSE and on which the IF...THEN instruction 


acts accordingly. 


EXAMPLES: 
100 IF(A>10) AND (B= 0) THEN GOTO 20 
200 ІЕ(А-0) OR (В-0) THEN STOP 
300 IF NOT (А = В) THEN PRINT ‘‘A<>B”’ 
These all mean: 

IF [combined result is TRUE] THEN (do it) 

IF [combined result is FALSE] go to the next line of the program. 
Using logical operations is a way of combining conditional operators in a 
statement. For example: 

IF [(condition 1) AND (condition 2) AND (condition 3)] 

evaluates as TRUE or FALSE] THEN...act accordingly. 

60 IF ((A>B) AND (C>A) AND (D>C)) THEN STOP 


AND 
IF (CONDITION 1) AND (CONDITION 2) THEN (RESULT) 
TRUE TRUE TRUE 
TRUE FALSE FALSE 
FALSE TRUE FALSE 
FALSE FALSE FALSE 


EXAMPLE: 
Condition 1- My age is > 12 years 
Condition 2- My age is < 20 years 


Result – І am a teenager. 
IF (my age > 12 years) AND (my age < 20 years) THEN (I am a 
teenager). 
Program 


10 PRINT “INPUT AGE” 
20 INPUT A 


264 


30 IF (A>12) AND (A<20) THEN GOTO 60 
40 PRINT “YOU ARE NOT A TEENAGER” 
50 STOP 

60 PRINT “YOU ARE A TEENAGER” 


OR 
IF (CONDITION 1) OR (CONDITION 2) THEN (RESULT) 
TRUE TRUE TRUE 
TRUE FALSE TRUE 
FALSE TRUE TRUE 
FALSE FALSE FALSE 
EXAMPLE: 
Condition 1 — I earn wages 
Condition 2 — I get pocket money 
Result – I have money 
IF (I earn wages) OR (I get pocket money) THEN (I have money). 
Program 


10 PRINT “INPUT AMOUNT OF WAGES AND POCKET 
MONEY YOU GET” 

20 INPUT W 

30 INPUT P 

40 IF (W»0) OR (P>0) THEN GOTO 70 

50 PRINT “YOU HAVE NO MONEY” 

60 STOP 

70 PRINT “YOU HAVE”’;W + P;‘‘POUNDS”’ 


NOT 
IF [NOT (CONDITION)] THEN (RESULT) 
TRUE FALSE 
FALSE TRUE 
EXAMPLE: 
CONDITION - I have money 
RESULT — I do not have money 
IF [NOT (I have money)] THEN (I don’t have money) 
Program 


5 PRINT “ARE YOU A LIAR?” 
10 PRINT “ІМРІУТ AMOUNT OF MONEY" 
20 INPUT M 
30 IF NOT (M>0) THEN GOTO 60 
40 PRINT “APPARENTLY YOU DO NOT HAVE MONEY" 
50 STOP 
60 PRINT “YOU DO HAVE MONEY REALLY ?" 


265 


R7: Multiple Logic on Conditions 


Multiple logical operations on conditions are often useful. 


They take the form: 


AND AND AND 
IF [(C1) = | (C2)] к= | [(C3) ке | (C4)] THEN... 
Where СІ = Condition 1 

C2 = Condition 2 
Condition 3 
C4 = Condition 4 


e.g. IF [(C1 AND C2) OR (СЗ AND С4)] THEN... 
The above statement means that: 
IF conditions 1 AND 2 are obeyed 

OR conditions 3 AND 4 are obeyed 
then the combined expression is TRUE, and the instruction 
will be executed, i.e. either pair of conditions being both 
TRUE will give the result. 

IF (С1 AND C2) AND (C3 AND C4)] THEN 

In this statement all four conditions must be true to give the 
result. 


e 
оз 
I 


What do the following imply? 
IF [(C1 OR C2) AND (C3 OR C4)] THEN... 
IF (Сі OR C2) OR (C3 OR C4)] THEN... 
Notice the importance of brackets in the statements. 

Their placing gives a clear logical meaning to an expression. Any 
bracketed expression will be evaluated first. The result (““TRUE”’ or 
"FALSE") obtained from the bracketed expression will be used in 
evaluating the whole expression. 

A practical example of multiple logical operations on conditions 
would be obtaining a loan. The relevant conditions could be: 

C1 = Husband is over 21 years old 

C2 = Husband's salary is over £5,000 per year 

C3 = Wife is over 21 years old 

C4 = Wife's salary is over £5,000 per year. 

We can write a statement which indicates whether the bank will grant 
the family a loan to buy a car: 

IF (Сі AND C2) OR (C3 AND C4)] THEN loan granted. 


Exercises 
1. Key in and run the program which illustrates this: 


10 PRINT "INPUT AGE OF HUSBAND" 

20 INPUT HA 

30 PRINT “INPUT AGE OF WIFE" 

40 INPUT WA 

50 PRINT "INPUT P.A. INCOME OF HUSBAND" 
50 INPUT IH 


266 


70 PRINT “INPUT P.A. INCOME OF WIFE" 
80 INPUT IW 
99 IF (НА>21 AND IH>= 5000) OR 
(WA>21 AND IW>= 5000) THEN GOTO 120 
100 PRINT "NOT ELIGIBLE FOR LOAN" 
110 STOP 
120 PRINT "LOAN AVAILABLE" 


2. Write a program which inputs four numbers and outputs a 
message if any of them are zero. 


R8: Logical Operations on Numbers 


The logical operations AND, OR, NOT when applied to numbers 
return a number as the result. The rules for the operations on two 
numbers X and Y are given in the following truth tables. Non-zero 
values may be either positive or negative. 


AND 





i.e. X AND Y returns X if Y is non-zero 
0 if Y is zero. 





i.e. X OR Y returns 1 if Y is non-zero 


X if Y is zero. 





i.e. NOT Y returns @ if Y is non-zero 
1 if Y is zero 


EXAMPLES: 
7AND3 = 7 
7 AND 0 = 0 
ЭШК Л = | 


267 


JORO = 5 
NOT 8 = 0 
NOT @ = 1 


Exercises 


1 Key inthe examples given above as direct commands, and verify 
the rules of logical operations on numbers. 
2 Keyin and run the following programs: 


LOGIC 1: 


5 REM "LOGIC 1" 
10 INPUT A 
20 INPUT B 
30 PRINT "А=";А,"В="; В 
40 PRINT "A AND B-";A AND B 
50 PRINT "A OR В=";А OR B 
60 PRINT "NOT B=";NOT B 
70 GOTO 19 


Results: 
А-77 В 
A AND B=77 
А ОК В = 1 
NOT В = 0 


li 
н> 
сл 


А = 77 В =Q 
А AND В = 0 
А OR В = 77 
NOT В =1 
LOGIC 2: 


5 REM "LOGIC 2" 

10 REM **THIS PROGRAM TESTS THE LOGICAL OR 
OPERATOR ACTING ON A NUMBER AND A 
CONDITION TOGETHER** 

30 PRINT "Ү-10%(7 OR А=3) " 

35 PRINT 

40 PRINT "INPUT A VALUE FOR A PLEASE" 

45 PRINT 

5@ INPUT A 

55 LET Ү-10%(7 OR A=3) 

60 PRINT "IF A=";A,"THEN Ү-";Үү 

65 PRINT 

70 PRINT "WHAT ARE YOUR CONCLUSIONS??" 

75 PRINT 

88 PRINT 

90 GOTO 39 


LOGIC 93: 


2 MEM “LOGIC 3" 

10 INFLT А 

20 FRINT 77-(10 AND A=) 
30 GOTO 10 


268 


R9: Priority 


OPERATOR PRIORITY 
= & >, «аб, ll 5 
NOT 4 
AND 3 
OR Ж 


Priority rules are strictly obeyed. If brackets are not used properly 
when logical operators act on conditions the desired result will not be 
achieved. For example: 


NOT (**FALSE'' AND ‘‘FALSE’’) 
gives NOT “FALSE” 
= “TRUE” 

BUI 

NOT “FALSE” AND “FALSE” 
gives “TRUE” AND ‘‘FALSE”’ 
= “FALSE” 

Completely the opposite! 


Exercises 


1 Key and and run this program, which checks priority. 

10 LET A=1 

20 LET B-1 

30 PRINT NOT (A - 0 AND B = 0) 

40 PRINT NOT A-0 AND B- 0 
2 What result would the following give? 

PRINT 5 AND 3 OR 0 OR NOT 7 AND 4 

3 Key in and run program ''LOGIC 4”, which tests priorities: 
REM "LOGIC 4" 
REM **THIS PROGRAM TES'TS MU 


LTIPLE LOGIC OPERATORS** 
10 LET A-5 AND 3 OR @ OR NOT 7 


мл 


AND 4 

20 PRINT "5 AND 3 OR @ OR NOT 
7 AND 4="; A 

30 PRINT 

40 PRINT 


50 LET B=((4 AND 2) AND МОГ (0 
AND 3)) OR ((3 OR Ø) AND (4 
OR 0)) 

60 PRINT "((4 AND 2) AND NOT ( 
0 AND 3)) OR ((3 OR 0) AND 
(4 OR 0))-";В 


269 


R10: Logical Operations with Strings 


1 Logical operations using AND, OR and NOT may be 
performed on conditional string expressions. For 
example: 

10 IF (A$ = B$) AND (C$ = D$) OR (D$ = E$) THEN... 
50 PRINT NOT AS = BS. 

2 The AND operator may be used directly between a string 

and a number. For example: 
PRINT (A$ AND N) 
The result of this operation is given by the truth table. 


—— 


< ECA W 
EF | ULE 


i.e. A$ AND N returns A$ if N is non-zero 
and a null string if N is zero. 
3 Two strings cannot be directly operated on by any logical 
operator because strings cannot have logical values. For 
example: 













A$ AND B$, A$ OR B$, NOT A$ 


are meaningless expressions. 


Exercises 


1 Key in PRINT NOT “A” =p 
апа PRINT YA” = B” AND “BM = G” OR "G'a"E" 
to test the rules of logical string operation. Try other 
combinations. 

2 Write a program which requests a name and then checks to see if 
it corresponds to several strings stored in the program, printing 
out a message to say if the word was found. 

3 Write a program to test the truth table for A$ AND N. 


R11: Logical Operations Between Strings and Conditions 


Only the AND operator may be used. 
The rule is the same as for strings and numbers. 





A$ AND C gives A$ if C is “ТЕСЕ” 
A$ AND C gives a null string if C is “FALSE” 


C can be either a string condition or a numeric condition. 


270 


EXAMPLES: 


PRINT “А” AND 3 =3 gives A 

PRINT “А” AND 3 = 4 gives the empty (null) string 
PRINT “А” AND “В” = *B" gives А 

PRINT “A” AND “B” = “С” gives the null string 


Exercises 


1 


R12: 


Key in and run LOGIC 5, which illustrates string and condition 
use. 


5 REM "LOGIC 5" 

10 LET Х5-”АВ” 

2) LET YSe"Ac* 

30 PRINT (2 AND X$»Y$) 

40 PRINT (7 AND X$«Y$) 

50 PRINT (5 AND X$-Y$) 

52 PRINT 

54 PRINT 

60 LET Р5-"1" 

70 LET Q$="2" 

80 PRINT (33 AND PS$>Q$) 

90 PRINT (66 AND Р5<05) 
100 PRINT (99 AND Р5-06) 
102 PRINT 
110 PRINT «со я ABUEL ниди м 
112 PRINT 
120 PRINT "AND mW que uu SW 


Results: 


Soc © < Sd 


SO "VAM “АСТ” 

AND vy] tte eet 
Alter the values of X$, Y$, P$ and O$ and run the program again 
each time. 
Alter the program to allow various strings and numbers to be 
input, and print out the relationships. 
Logical Operations Between Numbers and Conditions 


N AND C 


N OR C 


271 


Where N is a number 

and C is a condition: 
either a string condition e.g. A$ = “A” 
or a numeric condition e.g. B = 7 


N FALSE 0 N 
These are the same rules as with logical operations between 
numbers. 





N AND C gives N if C is “ТЕГЕ” 
N AND C gives 0 if C is “FALSE” 
N OR C gives 1 if C is “ТЕГЕ” 
N OR C gives N if C is “FALSE” 


Exercises 


1 Analyse, key in and RUN the following statements, and confirm 


the rules. 
PRINT TANDA = “A~ 
PRINT P AND “A” = “А” 
PRINT 7 AND ‘‘A”’ = “В” 
PRINT 0 AND “A” = “ВБ” 
PRINT 7 OR “A” = “A” 
PRINT 0 OR “A” = “А” 
PRINT 7 OR “А” = “p” 
PRINT 0 OR “А” = “В” 


2 Кеуіп and run this program. 
Input B as 3 and 5. 
10 INPUT B 
20 PRINT 7 AND B= 3 
30 PRINT 7 OR B=3 
40 GOTO 10 


R13: Applications of Logical Operators 


Simple conditional tests 

Multiple conditional tests 

Multibranch GOTO and GOSUB 
Finding maximum and minimum values 
Checking characters input 

Checking input values 

Testing for zero 

Default values 


COND Qo GON m 


1 


2 


4 


Simple Conditional Tests 
IF (Logical Operation) THEN (statement). 


If the logical operation is TRUE the statement is executed. 
AND, OR and NOT operators are used. 

Multiple Conditional Tests 

IF [(Condition 1) AND (Condition 2) OR (Condition 3)] THEN 

(statement). 

If the multiple logical operations are TRUE the statement is 

executed. 


AND, OR and NOT are used. 
Multibranch GOTO Routines 


Using this technique, control may be transferred to any of a 


number of statement lines. 
Here we use the AND routine, whose default value is zero: 


GOTO (100 AND C1) + (200 AND C2) + (300 AND C3) 


C1, C2 and C3 are three conditions. 
Control is transferred to line 100 if C1 is TRUE 
200 if C2 is TRUE 
300 if C3 is TRUE. 


Similarly: 
GOSUB (100 AND C1) + (200 AND C2) 


Control is transferred to: 
the subroutine at line 100 if C1 is TRUE 
200 if C2 is TRUE 
300 if C1 and C2 are TRUE 
and the next line, if neither are true. 
Key in and run this program: 


10 INPUT A 
20 INPUT В 
30 GOTO (100 AND А=0)+ (200 А 
ND B=) 
40 PRINT A48 
50 STOP 
100 PRINT "A-Q.INPUT A AND B 
AGAIN" 
110 GOTO 10 
200 PRINT "В-0.ІМРОТ B AGAIN" 
218 GOTO 20 
300 PRINT "BOTH ZERO. INPUT A 
AND B AGAIN" 
318 GOTO 10 


Finding Maxima and Minima Values 


We use the AND operator to find the maxima and minima of 
two numbers X and Y. 


1@ INPUT X 

20 INPUT Y 

30 PRINT "MAX IS"; (X AND X>=Y) 
+(Y AND Y>X) 

40 PRINT "MIN IS"; (X AND X<=Y) 
%(Ү AND Ү<Х) 


273 





or we could program this as 


20 IF X >= Y THEN GOTO GO 
40 PRINT "MAX="3¥:" MIN="3X 
FQ TUF 


æ 


ео PRINT "MAX=";X;" MIN="sy 
Which do you think is the best method? 


Finding the largest number in a list is another application. We 
have a list of numbers A(1) to A(N). We can compare the first 
two, A(1) and A(2), and put the largest of these into a variable L 
by the statement: 

LET L-(A(1)AND A(1)> = A(2)) +(A(2)AND А(2)>А(1)) 
We compare this value of L with the next number A(3) and 
make L take the larger value of the two and so on through the 
list. 

LET L=(L AND L> = A(3)) + (A(3) AND A(3)>L) 
The program asks us to input how many numbers will be in our 
list (N). We then input the numbers A(I). These are printed on 
the screen together with the largest value. Two loops are used, 
the first to input the numbers and the second to perform the 
comparisons. 


10 REM "LARGEST" 
20 PRINT "INPUT HOW MANY NUMBE 


30 INPUT N 
40 PRINT М 
50 DIM A(N) 
60 FOR I = 1 TON 
70 INPUT A(T) 
80 PRINT A(I);" "; 
98 NEXT I 
100 LET L =(A(1)AND А(1)>=А (2) 
)+(A(2)AND А(2)> А(1)) 
1102 FOR I = 3 TON 
120 LET L = (L AND L>=A(I)) + 
(A(I)AND A(I)> L) 
130 NEXT [I 
148 PRINT “LARGEST NUMBER IS " 
;L 


Key in and run the program. 

This is an appropriate place to emphasise the care needed in 
programming logical operations. There are two things that 
cause problems. The first is the setting of conditions, and the 
second is the grouping of these conditions in a logical sequence 
that will produce the required result. Any line the computer does 
not reject because of a syntax error will produce a result. Care is 
needed to get the right result. 

This can be illustrated by the question of deriving the larger of 
two numbers, using AND. The problems of non-rigorous use of 
the logical and relational operators can be illustrated by 
considering the following problem. We have two numbers X 


27% 


and Y. We know that AND can be used so that if we code a 
program line as LET M = X AND Х>Ү it will return the value 
of X if the condition is true. We want to use this to get the value 
of a maximum. The line above will produce zero if the condition 
Is not true. So we can combine two such tests in one line to get 
our maximum. We key in this sort of program (do it): 

10 INPUT X 

20 INPUT Y 

30 LET MAX =X AND Х>Ү +Y AND Ү>Х 

40 PRINT MAX 
Input some numbers and check the results. 

Something is wrong. Looking at the program, we see we need 
some brackets. As it stands, line 30 is actually a sequence of 
three conditions, joined by two AND operators. It reads ‘give 
MAX the logical value of (X) AND (X>Y + Y) AND (Y>X)’. 
Since all three conditions have to be true for the whole 
expression to be true, and since (X>Y + Y) and (Y>X) cannot 
both be true, we get zero. 

We make the expression more sensible, we hope, by changing 
line 30 to read: LET MAX = X AND (Х>Ү) + Y AND (Y>X). 

Key in this as a new line. Now try some inputs. 

If X is smaller than Y we get the value of X printed, and if X 
is greater than Y we get zero. We haven’t got the brackets right. 
There are still three conditions joined by two ANDs. We've 
changed the meaning, but not to what we actually want. If X 
and Y are non-zero, (X) is true, ((X>Y) + Y) is zero for smaller 
X, one (TRUE) for larger X, added to Y. This is non-zero, so is 
TRUE. If the last condition is TRUE (i.e. Y2X) then the 
combined expressions give X as the result. If it’s FALSE then 
the whole expression is FALSE and prints 0. Now we see what's 
wrong, we can put some more brackets in. 

Edit line 30 to read: LET MAX = (X AND(X>Y)) + (Y AND 
(Y>X)). 

Now try some inputs. The greater of the two numbers is 
returned, which zs what we wanted. If we now look at our 
working line, we can see (or should) that there are brackets we 
don’t need, although they don’t do any harm. Edit line 30 to 
read LET MAX = (X AND X>Y)+(Y AND Ү>Х) and check 
the greater value is still returned. So we're finished — or are we? 
Only if you didn't consider what happens if the numbers X and 
Y are equal. Input the two numbers as the same value and see 
what result you get. Both expressions are FALSE if the numbers 
are equal, so we get zero printed. 

The line should read: 30 LET MAX = (X AND X» = Y) «(Y 
AND Y>X). Just in case you're not convinced of the problems 
you can get into if you are not careful, enter the line as above 
and check that it works. Then edit it to read: LET MAX = (X 


275 


5 


AND X> = Y)+(Y AND Y> = X) and input values with X>Y, 
YX and X= Y. 

This sort of problem is only avoided by carefully thinking out 
the result required in the case of all inputs, and checking the 
logic before you code it in. If there are these possible problems in 
a four-line program, think of the potential pitfalls in a complex 
one! 

Checking Characters Input 

Control in a program can be achieved using the INKEY$ 
statement and checking which character is keyed in using 
combined conditional logic operations. We have seen this used 
in programs earlier in the text. 

The following program enables the numbers on the keyboard 
to be used as a Joystick, allowing you to move a dot in any 
direction on the screen. 

To move the dot in the following compass directions press the 
desired key. 


4 7 1 
5 8 
3 6 2 


= REM "JOYSTICK" 
10 REM *SPECTRUM: X=120) Y-80 
20 LET X-30 

30 LET Y-20 

40 PLOT X,Y 

50 IF ІМКЕҮФ ="" THEN GOTO 50 

80 LET A$- ІМКЕҮФ 

45 REM *SPECTRUM: 

70 OVER 1:PLOT X«Y 

70 UNPLOT X,Y 

75 REM *SPELTRUM: Х<255 

80 IF Х<63 AND CA$="S" DR Аф=" 
1" OR Аф="2") THEN LET X=X+1 

SỌ IF X50 AND (A$-"A" DR A$="2 
" OR A$-"5") THEN LET X-X-1 

95 REM *SPECTRUM: Y£175 

100 IF Y442 AND (A$="7" DR A$=" 
4" ПЕ Аф="1") THEN LET Y=Y+1 

110 IF Y50 AND (A$="6" DR A$="2 
" ОЕ A$z"3") THEN LET YzY-1 

120 GOTO 40 


276 


Analyse the program. 

Key it in and run it. 

Change the program to move the dot in larger Jumps. 

Change the program to move the dot in sixteen different 
directions. 


Checking Input Values 
The OR operator can be used to check that values keyed into a 


program are in range. For example, we are asked to input values 
for variables in the following ranges: 


A range 0-9 
B range 10 - 99 
C range 100 - 999 


Here is a program that checks values input: 


10 INPUT A 

20 IF A<@ ОН A»9 THEN GOTO 100 

30 INPUT B 

40 IF 8<10 OR B>99 THEN GOTO 2 
00 

50 INPUT C 

60 IF С<100 OR C>999 THEN GOTO 
300 

70 PRINT АТ 1,1;А; AT 1,8;B;A 
T 1,15;C 

80 STOP 

100 PRINT "INPUT A OUT OF RANGE" 

110 GOTO 10 

200 PRINT "INPUT B OUT OF RANGE" 

210 GOTO 30 

300 PRINT “INPUT C OUT OF RANGE" 

310 GOTO 50 


Testing for Zero 


We can use the NOT routine to check for zeros in a list of 
numbers. 


NOT (N) = 0 when N<>0 


NOT (0) = 1 
Here is a program which sets up a counter C, initialises it, and 
requests numbers to be input. If a zero is input NOT 0 = 1 and 


C is incremented by LET C = C + NOT (A(F)). 


5 DIM A(19) 
10 LET С-й 
20 FOR F = 17010 
30 INPUT A(F) 
35 PRINT A(F);" "; 
40 LET C=C+NOT (А(Е)) 
50 NEXT F 
60 PRINT "THERE ARE";C;"ZEROS" 


Key in and run the program. 
Default Values 
The default value of AND is zero. AND is therefore extremely 
useful in the addition of logical operations. For example: 
60 GOTO (100 AND A= 0) + (200 AND A»0). 


277 


The default value of OR is 1. OR is thus useful in the 
multiplication of logical operations. 

For example, the following program asks you to input any 
three digits in the range 0 – 9. The computer will generate three 
digits at random. 

You win £10, £100 or £1000 depending on how many digits 


you guess correctly. 


= REM "“GUESSANLM" 

10 DIM ACI) 

20 DIM BCS) 

20 PRINT “INPUT 3 DIGITS IN TH 
E RANGE 0-9 ONE АТ A TIME" 

40 FOR F=1 TO 3 

ФО INFUT ACF) 

ео PRINT ACF" "3 

70 LET E(CF2-2 INT € REND *10) 

SO NEXT F 

vo PRINT 

100 PRINT БСО?" ";B(2»);" "SBCs 
à 

110 LET Z=(10 OR (Aci) <> Bei) 
)%(1O ПЕ CACZ) <> B(2)))*(10 OF 
(ACS) <> Beso) 

120 IF Z=1 THEN LET Z=0 

130 PRINT “YOU WIN "32 

140 INFUT AS 

150 IF АФ-"Ү" THEN GOTO 20 

160 STOP 


278 


SECTION S: LISTS AND ARRAYS 


S1: Dimension 


The dimension statement DIM is used to reserve storage space 
for a LIST or ARRAY to contain numbers. DIM A (N) sets up 
an array A with space for N numbers. 

A may be any single letter A to Z. The Spectrum will accept 
both upper and lower case letters, but a(N) will signify the 
same array as A(N). 

N may be a number, a numeric variable or an expression. 


A dimension statement must be declared before the array can be used. 
This is usually done at the beginning of a program, unless the value of 
N is to be set equal to an expression or variable which will be calculated 
later in the program. 
There may only be one DIM statement on a line for the ZX81. 
These statements in a program: 
10 DIM А(10) 
20 DIM B(15) 
30 DIM C(30) 
will reserve storage for a list A containing 10 numbers, a list B 
containing 15 numbers and a list C containing 30 numbers. The values 
of each ELEMENT (number) in an array are automatically set 
(initialised) as zero. 
Error code 4 (‘out of memory’ on the Spectrum) will be displayed if 
there is no room for the array, i.e. if N is too large. 


S2: Index Variable 


The index variable N is used to locate a member of a list. 
We use the form A(N) to locate the N'th number of a list 
A(L), where 1< = N< = L. 
If N = 5, then A(N) refers to A(5), the fifth number in the 
list. 


The program below establishes a four element list, so that: 


A(1) = 1 
A(2) = 4 
A(3) = 9 
A(4) = 16 
and then prints out the second and fourth element. 
10 DIM A(4) 


20 FOR N=1 TO 4 
30 LET A(N) - N*N 

40 NEXT N 

50 PRINT “SECOND ELEMENT IS ”; A(2) 
60 PRINT “FOURTH ELEMENTIS ”; А(4) 


279 


S3: Lists 


Many types of problem involve a set of values and it is convenient to 
store such items in a list. The next program illustrates the idea. We 
assume a list of the squares of the first 20 integers is required. It is 
necessary to reserve storage for the twenty numbers (1, 4, 9 etc., up to 
400) and this is done in line 20. The loop (lines 30 to 50) puts A(1) = 1, 
A(2) = 4...A(20) = 400 and it is thus possible to use any item of this list 
at a later date, using the index variable. 

Line 60 prints out 4 16 36 and the loop (lines 80 — 100) will print out 
the complete list of numbers. 


tO REM "LIST" 

20 DIM A(20) 

30 FOR N=1 TO 20 

40 LET A(N)=N*N 

SO NEXT N 

60 PRINT AC2):" "rACAD;" "j 
ACE) 

70 PRINT 

80 FOR N-1 TO 20 

90 PRINT ACN) 

100 NEXT N 


S4: Examples of Lists 


We give below some example programs illustrating the use of lists. 
1 Simple allocation of elements in а list. Look at the program. 
What will be printed out when the program is RUN? Check by 


entering and running the program. 


REM *LIST1" 

DIM A(4) 

LET A(1)=19 

LET A(2)=58 

LET A(3)=72 

LET А(4)-20 
PRINT A(1)*A(3) 
PRINT 

PRINT A(3)-A(2) 


2 Allocation of values to the elements in a list using a loop and the 
INPUT statement. The value of the control variable (N) of the 
loop is used to specify each element of the list in turn. Again, 
work out the results of the program, then check by keying it in 


and running it. 


REM "LIST2" 

DIM A(4) 

FOR N-1 TO 4 

PRINT "TYPE A(";N;")" 


280 


50 INPUT A(N) 
60 NEXT N 
70 PRINT A(1)*A(3) 
80 PRINT 
99 PRINT A(3)-A(2) 


3 АП lists used in a program must be dimensioned, with each 
dimension statement on a separate line. Hand trace this 
program and decide what the 10 elements in list B(N) are. Check 
by entering and running the program. 


5 REM "LIST3" 
19 DIM А(20) 

20 DIM B(10) 

30 FOR N-1 TO 20 
40 LET A(N)=N*N 
50 NEXT N 

69 FOR N-1 TO 10 
70 LET B(N)-A(2*N)-A(2*N-1) 
80 NEXT N 

90 FOR N-1 TO 10 
109 PRINT B(N) 
110 NEXT N 


4 А variable may be used in a DIM statement, provided its value 
Is assigned before the DIM statement is reached. Enter program 
“LIST4”. Run the program for X = 20. 


= КЕМ “LISTA” 

10 INFUT X 

ZO DIM A(X) 

20 FOR N=1 TO X 
40 LET АСМ) = FRR N 
eO PRINT ACN) 

60 NEXT М 


5 The program “ОНМ5 LAW?” illustrates the use of lists to store 
data from a set of electrical circuit experiments. The voltmeter 
and ammeter readings from each experiment are stored in the 
lists A(N) and V(N) as they are input. Notice that it is essential 
to dimension storage space for the derived list of results, R(N), 
(line 60). The loop (lines 90 to 140) enables the readings to be 
stored for use in the later loop (lines 180 to 220), which performs 
the calculation and prints out the results of each experiment, 
giving the current in amps, the voltage in volts, and the 
resistance in ohms derived by the formula, R = V/I in line 190. 

Line 179 initialises a variable T which has each resistance in 
turn added to it. This enables line 250 to print the average 
resistance value. 

10 REM “OHMS*LAW" 

28 PRINT "OHMS LAW RESULTS" 

30 PRINT "UP ТО 20 PAIRS OF R 
EADINGS" 

40 DIM А(20) 


50 DIM У(20) 
60 DIM R(20) 


201 


70 


80 

90 
100 
110 
120 
130 
140 
150 


160 


170 
180 
190 
200 
210 


220 
230 


240 
250 


PRINT "TYPE NUMBER OF SETS 
OF READINGS" 

INPUT X 

FOR N=1 TO X 

PRINT "TYPE CURRENT IN AMPS" 
INPUT A(N) 

PRINT "ТҮРЕ VOLTAGE IN VOLTS" 
INPUT V(N) 

NEXT N 

PRINT "AMPS"; TAB 8; "VOLTS"; 


TAB 16; "OHMS" 
PRINT U*#*#*kkkkkkkkkkkkkkkkk 


***k 

LET Т-й 

FOR N-1 TO X 

LET R(N) =V(N) /A(N) 

LET T=T+R (N) 

PRINT A(N);TAB 8;V(N);TAB 1 
6;R (N) 


NEXT N 
PRINT U**kkkkkkkkkkkkkkkkkkk 


ТР 

PRINT 

PRINT "AVERAGE RESISTANCE " 
:Т/Х;" OHMS" 


Notice that if lines 70 and 80 had come before the DIM 


statements, 


we could use DIM A(X), etc. to set the size of the 


arrays exactly, as in program LIST4 above. 
6 А similar type of program is shown below. This shows image 
positions (V) and magnifications (M) for a convex lens, given 


the focal length of the lens (F) and the object distance (U). 


5 REM "CONVEXLENS" 


10 


PRINT "THIS PROGRAM SHOWS THE POSITION AND 
MAGNIFICATION OF ‘THE IMAGE PRODUCED BY A 
CONVEX LENS" 

PRINT V e e ee eee eee eee dec dee dee ee e e de e Ax (n 
DIM U(12) 

DIM V(12) 

DIM M(12) 

PRINT "TYPE FOCAL LENGTH IN CM." 

INPUT F 

PRINT "TYPE OBJECT DISTANCE IN CM." 

FOR N-1 TO 12 

INPUT U(N) 

LET V(N)=U (N) *F/ (U (N)—F) 

LET M(N)-V (М) /U (N) 

NEXT N 

PRINT "U";TAB (8);"V";TAB (22); "M" 

FOR N-1 TO 12 

PRINT U(N);TAB (8);V(N);TAB (22);M(N) 
NEXT N 


The screen display will look like this: 


282 


THIS PROGRAM SHOWS THE POSITION 
AND MAGNIFICATION OF THE IMAGE 


PRODUCED BY A CONVEX LENS 
kkkkkkkkkkkkkkkkkkkkkkkkkkkkkk 
M 


U 

10 -13,333333 “143353333 
20 -40 “2 

30 -120 -4 


39.555 -3555.5056 -89.887639 
40.555 2922.8829 72.072073 


50 200 4 

60 120 2 

70 93.333333 1.3333333 
80 80 1 

90 72 0.8 

100 66.666667 0.66666667 
120 60 0.5 


S5: String Arrays 


The DIM statement for string arrays has the form 
DIM A$ (N,L) 

where N = number of strings and L = the fixed length of each 
string. A may be any single letter A to Z, but must NOT be 
the same as a simple string variable. Each string is set to 
contain L spaces initially. 

DIM A$(3,4) will reserve storage space for 3 strings 
A$(1),A$(2),A$(3), each of length 4, in the string array А8. 


Each letter of each string can be accessed separately, as with a string 
variable. A$(2,3) will return the third character of the string A$(2). 
Substrings may also be allocated by a statement such as A$(2,1 TO 2), 
which will return the first and second characters of A$(2). For example, 
if A$(2) = “EFGH' then: 
A$(2,2 TO 4) = “FGH” 

The two programs below show these operations. Key them in and run 
them. Note that spaces may be included as letters, as can any other 
characters useable in a string. 


If we have: 
20 DIM А%(2.28) 
20 LET A$i025z"AEDC Еж G" 
Шеп АФ(2%40-" " 
апа АФ(2:35 TO Ез-"Еж G" 
1) 5 REM "STRING*ARR1" 


10 DIM А5(4,3) 

15 PRINT "ТҮРЕ ІМ LETTERS THRE 
E AT A TIME" 

20 FOR N=1 TO 4 

30 INPUT AS(N) 


40 NEXT N 

50 PRINT A$(4,3) ;" ";A$(3,2) 

70 PRINT 

80 PRINT A$(1);" ";A$(2);" "; А 
$ (3) 


283 


2) 10 REM "STR*ARR2" 
20 DIM AS(3,4) 
30 LET A$(1)="ABCD" 
40 LET A$(2)="EFGH" 
38 LET AS(3)e"IJEL" 
50 PRINT A$(2,4) ;" ";A$(3, 2) 
70 PRINT 
80 PRINT AS(2,2 TO 4) 
90 PRINT 
100 PRINT А5(1,3 TO 4) 


S6: Two Dimensional Arrays 


A 2-D (two dimensional) numeric array is dimensioned by the 
statement: 
DIM A(R,C) 
where À is any letter, R is the number of Rows and C is the 
number of Columns. 
All elements are set as zero. 


The simple array is one-dimensional, and contains just a linear 
sequence of items. Arrays can have more than one dimension: 
4 6 8 
10 12 14 
16 18 20 
22 24 26 
This is a numeric array consisting of £ rows of numbers in 3 columns. 
Storage would be reserved by the statement: 
10 DIM A(4,3). 
In an array A(R,C) we can access any element, so that in the array 
above: 
A(2,1) = 10 A(3,2) = 18 etc. 
An array of two (or more) dimensions is also known as a MATRIX 
(plural matrices). 
The following program establishes an array and prints out two 
selected elements and then the complete array: 
“0 REM "ARRAY" 
20 DIM А(10:9) 
20 FOR R=1 TO 10 
39 FOR Cel TO F 
40 LET ACR» CO ZEXC 
30 NEXT C 
60 NEXT Е 
70 PRINT Ас10%62»АС2%32 
Бо РЕІМТ 
зо FOR К=1 TO 10 
100 FOR C=1 TO 7? 
110 PRINT TAB S#Cr ACE C33 
120 NEXT С 
120 РЕІМТ TAE 4; 
140 NEXT К 


Line 20 allocates the appropriate storage. Nested loops (line 30 — 60) 
are used to allocate values to the elements in the array. Line 70 prints 


284 


out two elements in the array. Nested loops (line 90 to 140) print out 
the complete array. 
Why is line 130 required? 
In order to keep track of the elements of an array we need to have a 
system. In general it is easiest to use R to represent the Rows and C the 
Columns and to always access the rows before the columns. 


Note the use of the TAB function to give a clear printout. 


] 


2 


3 


2 3 
4 6 
6 9 
8 12 
10 15 


4 5 6 7 8 9 


8 10 12 14 16 18 


16 20 24 28 32 36 


20 25 30 25 40 45 


etc. 


String arrays can also have more than one dimension. 


2-D String arrays are dimensioned by a statement of the form 


DIM A$(R,C,L) 


where R is the number of Rows, C is the number of Columns 
and L is the length of all strings in the array. 


Try this program: 


10 
20 
30 


40 
50 
60 
65 
70 
80 
99 
100 
110 
120 
130 


REM "2DSTRING" 
DIM AS (3, 3,53 

PRINT "TYPE WORDS 5 LETTERS 
OR LESS" 

FOR R-1 TO 3 

FOR C=1 TO 3 

PRINT АТ 2,0;"ROW ";R;" COL ";C 
INPUT AS(R,C) 

NEXT C 

NEXT R 

FOR R-1 TO 3 

FOR C-1 TO 3 

PRINT AT R*4,C*8;AS(R,C) 
NEXT C 

NEXT R 


Key this in and run it. Try some appropriate entries for the rows and 
columns, as the routine in line 60 gives a cue for which entry is next. 
This is a useful routine for use with multiple entry INPUT routines, 
since it is very easy to forget which entry 1s next. One run of this 
program gave a final screen display like this: 


285 


TYPE WORDS 5 LETTERS OR LESS 


ROW 3 COL 3 
START 2ND THIRD 
FOUR FIVE SIXTH 


SEVEN EIGHT FINAL 


Note also line 110, where both control variables of the nested loops are 
used to format the printout using the PRINT AT instruction. 


87: Multidimensional Arrays 


Multidimensional arrays are available for both numbers and strings, 
although a 3-D string array is rarely something needed in a program! 
The easiest way of thinking of these arrays is as follows: 

A (P, R, O) is a 3 dimensional array: page, row, column 

А (B, P, R, C) is a 4 dimensional array: book, page, row, column. 
A 5 dimensional array would be a library, on the basis of this analogy. 
These arrays require DIM statements to reserve the necessary storage. 
A simple example of a 3 dimensional array (which needs 3 nested 
loops) is given below. 


10 REM "3DLIST" 
100 DIM A(3,2,4) 
110 FOR P-1 TO 3 
120 FOR R=1 TO 2 
130 FOR C=1 TO 4 
140 LET A(P,R,C)=P*C*R 
150 NEXT C 
160 NEXT R 
170 NEXT P 
180 PRINT A(2,1,3) 
190 PRINT 
200 FOR Р=1 TO 3 
210 FOR R=1 TO 2 
220 FOR С-1 TO 4 
230 PRINT A(P,R,C);" "; 
240 NEXT C 
245 PRINT 
250 NEXT R 
255 PRINT 
260 NEXT P 


The similar program below, extended by a dimension, shows a 4 
dimensional array printed out in a suitable form. 


286 


10 REM “4DARRAY" 
100 DIM A(2,3,4,5) 
110 POR B=) TO 2 
126 FOR P=1 TO 3 
130 FOR R=1 TO 4 
140 FOR Cz] TO 5 
150 LET A(B,P,R,C) B*P*R*C 
160 NEXT C 
170 NEXT R 
180 NEXT P 
190 NEXT B 
200 PRINT А(1,2,3,4):" ";A(2,2,3, 3) 
210 PRINT 
220 POR В-1 ТО 2 
230 FOR Р-1 TO 3 
235 PRINT "BOOK";B;"/PAGE";P 
240 FOR R=1 TO 4 
250 FOR C=1 TO 5 
260 PRINT A(B,P,R,C);" “> 
270 NEXT C 
280 PRINT 
290 NEXT R 
300 PRINT 
310 NEXT P 
320 PRINT 
330 NEXT B 


Here's a 3-D string version to try. Input only two letters at a time. 
Actually it doesn't matter, the computer will ignore any characters in 
excess of 2, since that 1s the dimensioned length. 


5 REM "3D*STR*ARR" 
10 DIM A$(3,3,3,2) 
20 FOR P-1 TO 3 
30 FOR R=1 TO 3 
40 FOR C=1 TO 3 
50 INPUT AS$(P,R,C) 
60 NEXT C 
70 NEXT R 
80 NEXT P 
90 FOR P=1 TO 3 

100 FOR R=1 TO 3 

110 FOR С-1 TO 3 

120 PRINT АТ R*3, (P*10-10)4C*3; 
AS (P, R,C) 

130 NEXT C 

140 NEXT R 

150 NEXT P 


Work out how the PRINT AT expressions work. 
$8: Use of Arrays 


A simple example of the use of 2-D arrays is shown in the seat booking 
program below. A small theatre consists of 10 rows of seats with 6 seats 
in each row. Some seats may already be reserved. These are input 
when the program is run. When a new booking is made the requested 
seat, if available, is sold. If the seat is not available a seat in the same 
row is offered. If no seat in that row is available the customer is asked 
to choose another row. 


287 


The sections of the program are as follows: 


1 


4,2 


4.3 


Initialise an array to represent the 10 rows of 6 seats (line 30). 
All elements in this array are 0, and represent unbooked seats. 
Input seats already booked (lines 40- 130). 

Input row and seat number of booked seats. If input is @ for the 
row number, program goes to 2.3. 

If seat already booked (array element = 1), print message to 
user. Seat is booked by placing a 1 in the appropriate array 
element. 

Program prints prompt, then halts until C is input. 
Customer request for seat is input (lines 165 ~ 240). 

Row and seat required are input. If seat already booked (array 
element = 1), program goes to 4. 

Seat is booked. 


Menu is printed to enable user to choose to book another seat, 
or to view seating plan. 

If seat booking is requested, program returns to 3.1. If seating 
plan option is chosen, program goes to 5. 

Seat unavailable module (lines 300 - 450). 

Seat unavailable message is printed, then the variable SEATS 
is set at zero, and the loop checks if at least one seat is free in 
this row, setting SEATS = 1 if a seat is free (Current Row R, 
checked for S(R,1) to S(R,6)). 

If no seats are free in this row (SEATS = 0), program passes to 
line 440 and prints message, then returns to menu (3.3). 

If at least one seat is free, the loop at lines 390 to 410 prints out 
the numbers of the seats free, and the program returns to the 
menu. 

View Seat Plan Module (lines 500 — 600). 

Nested loops are used to display seat plan, row 10 being at the 
top, as 078 and 175. 

Copy option is given, to print out seating plan. 

Menu presented for end of program or return to book seats. 
Program goes to 3.1, or proceeds to 6. 

Program ends. Instructions given to restart if required without 
using RUN and clearing the data stored in the array. 


10 КЕМ “THEATRE” 
20 REM ##INITIALISE ARRAY ++ 


30 DIM 2С(10%442 
35 REM **xINSERT SEATS ALREADY 
жжрГІІКСЕТІ ж 


40 FRINT "INFUT SEATS THAT ARS 


BOOKED, “a "INPUT О TO FINISH" 
S0 FRINT "ROW?" 
60 INPUT F 


70 IF R=O THEN GOTO 130 
80 PRINT "SEAT?" 
зо INFUT C 


288 


100 IF 5(ҒаГ2с1 THEN PRINT "ROW 

"Е" SEAT "FCs" ALREADY": “BOOK 
ЕП " 

110 LET 5(КзГ2т1 

120 GOTO 50 


ізо ELS 

140 PRINT “INPUT C TÜ PROCEED T 
Q BOOKING. " 

150 INFUT АФ 

160 CLS 

165 REM w*CUSTOMEF REQUEST FDF3 

Xx EAT X% 

170 PRINT "ТҮРЕ ROW RERUIRED" 
120 INFUT F 

170 PRINT "TYPE SEAT NUMBER" 
200 INFUT C 

210 IF SctR»C)=1 THEN GOTO 300 
220 LET S(R»C)=1 

230 PRINT “THIS SEAT FREE. NOW E 
ODKED. " 

240 PRINT "ROW "Е" SEAT "С 
250 FRINT 

260 PRINT “BOOK ANOTHER SEAT (S 
ӘСЕ VIEW", “SEATING PLAN CFO ТІМЕН 
T $ OR P" 

270 INFUT АФ 

280 IF Ag="S" THEN GOTO 170 

290 GOTO 500 


300 FEM ** SEAT UNAVAILABLE жж 
310 PRINT “REQUESTED SEAT NOT A 
VAILABLE" 

320 LET SEATS=0 

330 FOR N=1 TO 6 

340 IF ЕСЕ» М) =1 THEN GOTO 360 
350 LET SEATS=1 

360 NEXT N 

370 IF SEATS=0 THEN GOTO 440 
380 PRINT "SEATS FREE: "; 

390 FOR М=1 TO 6 

„200 IF S(R|N)=O THEN FRINT М; " 
410 NEXT N 

420 PRINT "." 

430 GOTO 450 


440 PRINT "ND SEATS ARE FREE IN 
ROW “FR 
450 GOTO 260 


490 REM s* SEATING FLAN жж 

500 CLS 

510 FOR R=1 TO 10 

520 LET X=11-R 

530 PRINT TAB 8: "ROW "FX; TAB 1 


S40 FOR C=1 TO 6 
550 PRINT SCX)? 
560 NEXT С 
570 FRINT 
580 NEXT F 


289 


590 PRINT +s+s"INPUT C TO COPY ñN 
Y TO PROCEED” 

600 INFT AS 

610 IF A$z"C" THEN COPY 

620 PRINT аз "INPUT E TO ЕМІЗЕ T 
О BOOK SEATS." 

630 INFUT АФ 

640 IF A$-"E" THEN GOTO 670 

650 CLS 

660 GOTO 170 

670 PRINT "PROGRAM STOPPED. US 
GOTO 170 ТО", "RESTART. " 

630 STOP 


690 REM ** END PROGRAM жж 


Screen display, at end of seat plan print routine (the first prompt has 
been responded to with a user input): 


ROW 10 000000 


ROW 9 000000 
ROW 8 000000 
ROW 7 000000 
ROW 6 000000 
ROW 5 000000 
ROW 4 000100 
ROW 3 100000 
RW. 2 дылы 
ROW 1 000000 


INPUT C TO COPY,ANY TO PROCEED 
INPUT E TO END,S TO BOOK SEATS. 


The variables used in the theatre booking program are as follows: 


S(10,6) 


SEATS 


“THEATRE” - DATA TABLE 


Array to store 10 rows of 6 seats (value 1 when seat 
booked, 0 when free). 

Current Row of array in processing. 

Current Seat number in processing. 

User Input string for menu choices. 

Marker used to indicate whether seats are free in current 
row. Set to 0 when no seats free, 1 when seats available. 
Loop variable. Value used in processing inside loops to 
check seat availability, and print seat numbers. 

Loop variable used to print seat plan. Note this is the 
same name as the variable for Rows above. This name 
may be used in two different ways in this program because 
the value of the simple variable R is re-initialised by the 
input at line 17@ on return to the seat selection routine. 

Variable used for reverse printing of seating rows. 


290 


C Loop variable for seats in seat plan printing. As with R 
above, re-initialised as simple variable on return to seat 
selection routine. 

Note that the use of variables in two ways, as with R and C in this 

program is only possible if the simple variables will be re-initialised 

every time they are used, otherwise problems can arise. A loop variable 
erases a simple variable of the same name. It would be better practice 
to use different names for the two types of variables. 


291 


SECTION T: SORTING SEARCHING AND STORING ARRAYS 


T1: Searching and Sorting 


Searching a list of numbers (or strings) for specified values can 
obviously be done much more efficiently if the numbers (or strings) are 
sorted according to some specified order, commonly alphabetical order 
or ascending numerical order. In electronic data processing groups of 
records (files) can be handled more efficiently if the records are pre- 
sorted into a specified order (e.g. by merging transaction files into a 
master file). Various techniques have been developed to sort data and 
several of the simpler methods are illustrated in this section together 
with two simple methods of searching lists. 

There is a considerable difference in the efficiency of the various 
sorting techniques depending on the type and volume of data to be 
sorted. A technique which is good for a random list of numbers may 
not be appropriate for a list in which only one number is out of 
sequence. For random lists the Quick Sort and Shell Sort techniques 
are very much faster than a Bubble Sort. Deciding on which is the most 
suitable method is largely a matter of experience and you should 
experiment using the different techniques for equivalent sets of 
numbers, timing the sort procedures. 

Many sorting algorithms exist, and we will first deal with the 
simplest. 

The BUBBLE SORT is used for sorting numbers (or strings with 
appropriate alterations) into ascending or descending order. The 
principle of the bubble sort is to compare adjacent numbers and change 
positions if they are in the incorrect order. This is done for elements 1 
and 2, then 2 and 3, 3 and 4..Х-1 to X at the end of which the 
highest number is in the Xth position. This is repeated (and the next 
highest number bubbles up to the X ~ 1th position) and repeated 
again, until the ordering is complete. 

The following program is a bubble sort to put numbers into 
ascending order. The sorting routine itself 1s in lines 130 to 225. 


10 REM "BUBBLE" 
20 PRINT "TYPE NUMBER OF ITEMS 
TO BE SORTED" 
25 PRINT "MAXIMUM NUMBER 50" 
30 INPUT X 
35 IF Х>50 THEN GOTO 25 
40 DIM A(50) 
60 PRINT "TYPE NUMBERS ONE AT 
A TIME" 
75 LPRINT "UNSORTED LIST" 
80 FOR №] TO X 
90 INPUT Z 
100 LET A(N)-Z 
110 LPRINT A(N) ;" "; 
120 NEXT N 
125 LPRINT 


292 


130 REM **SORTING ROUTINE**** 
140 FOR N-1 TO X-1 

150 FOR M-1 TO X-N 

160 LET C=A(M) 

170 LET D=A (M+1) 

180 IF C<=D THEN GOTO 210 
190 LET A(M)=D 

200 LET A(M+1)=C 

210 NEXT М 

220 МЕХТ М 

225 REM ******gND SORT****** 
230 LPRINT "SORTED LIST" 

249 FOR N=1 TO X 

250 LPRINT A(N);" "; 

260 NEXT N 


Sample printout: 
UNSORTED LIST 
129 267 56 41 69 43 99 90 4 8 


SORTED LIST 
4 8 41 43 56 69 90 99 129 267 
То illustrate (һе operation of the program, we'll take the first four of 
these numbers and see how the program sorts them: 
Bubble sort for 4 numbers A(1), A(2), А(3), A(4) 
inputas L29, 26/, 530, 41 
Procedure: 
(1) Go through the list comparing successive number 
pairs. For example: 
A(1) and A(2), then A(2) and A(3). 
If А(1)>А(2) then they are swapped so that A(2) 
becomes A(1) and A(1) becomes A(2). If A(1) 
<A(2) then they are left as is. 
We see that the largest number in the.list will 
finally be in the highest position, 1.e. A(4). 
(2) On the first pass we make three comparisons and 
the largest number will end as A(4). 
On the second pass we make two comparisons, 
and the largest number will be in position A(3). 
On the third pass we make one comparison. 
The larger number will be A(2). 
No need for any more passes. Smallest number 
will be A(1). 
There are four numbers: so X - 4 
We need X - 1 passes: so N = 1 TO(X- 1) 
= 1 TO 3 passes 
For each pass we need from 1 to X — N comparisons: 
so M = 1to(X- N) comparisons 
Here is a diagram in table form of the operations performed in the 
course of the sort: 


293 


Table of Operations 


START |М-1|М-2|М-3 |ЅТАКТ |М = 1 a= M = 1 | FINISH 
E» 





A(1)129 | 129 129 56 
A(2)267 | 267 | 56 "6 129 | 41 
A(3) 56 267 | 41 129 
A(4) 41 267 A 


T2: Bubble Sort with Flag 


10 REM "SORTFLAG" 
20 PRINT "TYPE NUMBER OF ITEM 
S TO BE SORTED" 

25 PRINT "MAXIMUM NUMBER 50" 
30 INPUT X 

35 IF X550 THEN GOTO 25 

40 DIM А(50) 

60 PRINT "ТҮРЕ NUMBERS ONE АТ 

А ТІМЕ" 

70 PRINT "UNSORTED LIST" 

80 FOR N=1 TO X 

90 INPUT Z 

100 LET A(N)=Z 

110 PRINT A(N) ;" "; 

120 NEXT N 

125 PRINT 

130 REM **SORTING ROUTINE**** 
140 FOR N-1 TO X-1 

145 LET S=0 

150 FOR M-1 TO X-N 

160 LET C-A(M) 

170 LET D=A (M+1) 

180 IF C<=D THEN GOTO 210 

190 LET A(M)=D 
200 LET A(M+1)=C 

205 LET S=1l 

210 NEXT M 

215 IF S=0 THEN GOTO 230 

220 NEXT N 

225 REM *kkkkkkkpNDřkkkkk 

230 PRINT "SORTED LIST" 

240 FOR N-1 TO X 

250 PRINT A(N);" "; 

260 NEXT N 


In order to ensure that the sort is completed as quickly as possible, a 
flag (in this case the variable S) is introduced to indicate if it has been 
necessary to swap elements in the list. S = 1 when a swap has occurred 
and sorting wil continue until 5-0 at line 215. This prevents 
unnecessary sorting taking place. The procedure and program are 
otherwise the same as the bubble sort. The lines 145, 205 and 215 have 
been inserted into the ''BUBBLE'' program. 


294 


Exercise 


Draw up the table of operations for this program, as was done for the 
“ВОВВІЕ””. 


ТЗ: Alphabetic Sort 


The Bubble Sort (and all other sorts) may be used to sort strings by 
using appropriate string variables and string arrays. 


5 REM “ALPHASORT" 

10 PRINT "HOW MANY STRINGS" 
20 INPUT X 

30 PRINT "MAXIMUM 10 CHARACTERS" 
35 PRINT 

40 DIM А$(Х,10) 

50 FOR N-1 TO X 

60 INPUT AS(N) 

70 NEXT N 

80 PRINT "UNSORTED LIST" 

90 FOR N-1 TO X 

100 PRINT AS(N), 

110 NEXT N 

120 PRINT 

130 НЕМ **SORTING ROUTINE** 
140 FOR M=1 TO Х-1 

150 FOR N=1 TO X-M 

160 IF AS(N+l) >=A$(N) THEN GOTO 209 
170 LET Т5-А5(М-1) 
180 LET AS(N+1) =A$(N) 
190 LET AS(N) -T$ 
200 NEXT N 

210 NEXT M 

220 PRINT 

230 PRINT "SORTED LIST" 
240 FOR N=1 TO X 

250 PRINT AS(N), 

260 NEXT N 


Some care must be exercised if the above sort is to be used on numbers 
entered as strings. The example given below shows that it will work 
frovided one ensures that all numbers entered have the same number of 


figures. 
(1 Incorrect use: 


HOW MANY STRINGS 
MAXIMUM 10 CHARACTERS 


UNSORTED LIST 


129 99 
543 6 
456 897 
567 21 
345 45 


295 


SORTED LIST 


123 21 
345 45 
456 543 
567 6 
897 99 


(п) Correct use: 


HOW MANY STRINGS 
MAXIMUM 10 CHARACTERS 


UNSORTED LIST 


123 099 
543 006 
456 897 
567 021 
345 045 
SORTED LIST 

006 021 
045 099 
123 345 
456 543 
567 897 


Т4: Insertion Sort 


This is another type of sort which is more efficient than the Bubble Sort 
and is also the basis of an even faster sort called a Shell Sort. Speed is a 
prime consideration when sorting large amounts of data. 

Consider the list of numbers: 


3 2 5 4 1 


We start with the first entry іп the list. Then we take the second item, 
compare the two, and swap if necessary. Then the second is compared 
with the third, a swap performed if required, and 7f a swap was made 
the first and second are compared again, and swapped if necessary. 
Then the third item is compared with the fourth, and so on. The list 
above will be sorted like this: 


296 


Swap 3 2 
у 4 
2 3 
i23 
3 9 
777773 
Swap 5 4 
у + 
4 5 
9 
Swap 5 1 
+ + 
1 5 
Бе «> 
Swap 4 1 
у + 
1 4 
es: 
Swap 3 1 
+ 4 
1 3 
— a 
Swap 2 1 
V 4 
1 2 


Consider the list A(1), A(2) . . . A(X). To insert item A(I+ 1) in the 
correct position: 

Let T = A(I+ 1), then 

if T> = А(Т) no swap is necessary and no further comparisons аге 

required. 

if T<A(I) we let A(I + 1) = А(1 and we move on to А(1- 1), then 

if T» = A(I- 1),we let A(T) = T and insertion is complete 

if T<A(I- 1), we let A(T) = A(I - 1), and so on down the list. 


The various steps we will make in the program are therefore as follows: 


1) Set J 2 I and T = A(I +1) 

2) If T^ = A(J) let A(J + 1) = T and stop 

3) Let A(J + 1)= A(QJ) 

4) LetJ=J-1 

5) If J<1 let A(J + 1) = T and stop. If not, go to (2). 

6) Repeat for each value of I (from 1 to N-1) where 
N = number in list. 


297 


300 
310 
SAO 
330 
340 


280 


Program Listing 


REM "INSERT" 

РЕІМТ "HOW MANY NUMBERS?" 

РЕІМТ 

РЕІМТ 

ІМРІТ X 

DIM ñ(X) 

PRINT "ТҮРЕ NUMBERS" 

FOR N=1 TO X 

ІМРМТ ACN) 

NEXT N 

PRINT 

PRINT “UNSORTED LIST" 

ЕСЕ N=1 TO X 

PRINT AChND;" "3 

NEXT N 

РЕІМТ 

РЕМ FE Ж 3€ 3€ 9€ 3C KKH HHH EH 
жж SORTING MODULE жж 


FOR I=1 TO X-1 

LET J=I 

LET TzACI-*1) 

IF T >= ACI) THEN GOTO 270 

LET AtCJd+1)=A¢.)) 

LET J=J-14 

IF J >= 1 THEN GOTO 220 

LET ACJ+1)=T 

NEXT I 

REM 
XxEND SORT MODULE жж 
555525555522 22555 

РЕІМТ 

PRINT “SORTED LIST" 

ЕСЕ N=} TŪ X 

PRINT ACN)" "; 

NEXT N 

FEM xENIS x 


A trace of the program, using our example list again, can be shown like 


this: 





298 


T5: Shell Sort 


The procedure in this sort is to precede an insertion sort by a process 
which, if we consider a list of numbers to be placed in ascending order 
left to right, will move low values to the left and high values to the right 
more quickly. 

Consider an 8 element list A(8), holding the values: 74, 32, 59, 46, 
26, 9, 62, 42. The sort proceeds in the following stages: 


1) Divide the 8 by 2 and compare elements 4 positions apart in the 
list, swapping if necessary: 


A(1) A (2) A (3) А (4) A(5) А (6) А(7) А (8) 
74 32 59 46 26 9 62 42 
Сотраге А(1) апа А(5) Swap 
A(2) and A(6) Swap 
A(3) and A(7) In order - leave 
A(4) and A(8) Swap 
New list: 
26 9 59 42 74 32 62 46 


2) Divide the 4 by 2 and compare the elements 2 positions apart in 
the list and swap if necessary: 





26 59 
g me 
59 74 
42 (SWAP) 32 
74 (SWAP) 62 

42 32 46 
New list: 
26 9 59 32 62 42 74 46 


3) Divide 2 by 2 and compare elements 1 apart in the list, which is 
using the equivalent of an insertion sort to give the final order: 


9 26 32 42 46 39 62 74 
The steps we make in the program are as follows: 


a) Select an integer S (number of positions apart from 
comparison). This is usually taken as INT (N/2) where 


299 


b) 


c) 


N = number of items in the list. 

Sort the lists of items Š positions apart, by comparing and 
swapping if necessary. 

If S<1 then stop, since the list is sorted. 

If S>=1 then pick a new value of S (usually INT(S/2)), and 
repeat steps b) to d) as often as necessary. 


5 REM "SHELL" 

10 PRINT "HOW MANY NUMBERS?" 
20 INPUT X 

30 DIM A(X) 

50 PRINT "TYPE NUMBERS" 
60 FOR N-1 TO X 

70 INPUT A(N) 

80 NEXT N 

90 PRINT 

100 PRINT "UNSORTED LIST" 
110 FOR N-1 TO X 

120 PRINT A(N); " "; 

130 NEXT N 

140 PRINT 

198 REM **SORTING ROUTINE** 
200 LET S-X 

210 LET S=INT (S/2) 

220 IF S«1 THEN GOTO 400 
230 FOR K-1 TO S 

240 FOR I-K TO X-S STEP K 
250 LET J-I 

260 LET T=A(I+S) 
270 IF T»-A(J) THEN GOTO 312 
280 LET A(J+S) -A(J) 
290 LET J=J-S 

300 IF J»-1 THEN GOTO 270 
310 LET A(J+S) =T 

320 NEXT I 

330 NEXT K 

340 GOTO 210 

350 REM **END OF SORT** 
400 PRINT 

410 PRINT "SORTED LIST" 
420 FOR N-1 TO X 

430 PRINT A(N) ;" "; 

440 NEXT N 

450 REM **END** 


300 


Hand trace of Shell Sort 


Consider the 8 element list 74, 32, 59, 46, 26, 9, 62, 42. 
X =8. 


310 


T = 1 2 3 4 2 4 3 


2 
9 
)=74 A(6)=32 A(8)=46 


i 


A(1)=26 A(2)=9 A(7)=62 A(4) 


62 42 32 46 62 4 


At this stage (1) the list is 26, 9, 59, 42, 74, 32, 62, 46. 


210 
220 
230 
240 
250 
260 


S | 2 S=1 

Қ = 1 2 

[= J 2 3 4 5 6 2 4 6 

J = 1 2 3 4 5 6 2 4 6 

T = 59 42 74 62 46 32 42 46 
A(7)=74 





A(5)=62 A(8)=46 A(4)=32 A(6)=32 А(8)-46 


At this stage (2) the list is 26, 9, 59, 32, 62, 42, 74, 46. 


The final stage is the comparison of neighbouring elements using the 


insertion sort technique, to which the Shell Sort routine is equivalent 
when S = 1. This is perhaps more easily seen if we consider the trace 
below of the operation of the Shell Sort program on a simple 5-item list, 
in which only two passes need to be made. 


301 







I = 3 r = 2 I = 2 
J = 3 J=2 J = 2 Start 


T=A (5) T=A (4) T=A (5) Pass 2 


A(2)=4 





А(3)-1 
А(4)-3 


А(5)-5 


Тһе two methods of tracing а program illustrated here should show you 
the method by which a systematic analysis can be made of the changing 
values of variables in a program as processing proceeds. This is a 
procedure you should put to use when designing a program (i.e. in 
checking that the algorithm will work as intended) and when checking 
the operation of other people’s programs that you wish to analyse. The 
procedure is also a great help in debugging a program. Break points 
inserted into the program (STOP commands), after which you can 
print the values of variables by direct commands, or PRINT 
statements, inserted as appropriate to print the values of variables at 
each step in the program, will enable you to check that the values 
occurring in the program are the same as the ones your trace diagram 
shows. You can even LPRINT values to get a printout, if many passes 
are to be made in the program. 


T6: Quick Sort 


This provides a fast sorting technique which works by subdividing the 
list into two sub-lists and then subdividing the sub-lists. The principle 
of the Quick Sort is as follows: consider a list A(X) containing X 
numbers. We assume as an example that X = 8 and the numbers are as 
shown below. The following steps are carried out: 


302 


1) 


2) 


3) 


1) 


Initialise two pointers, I and J, at opposite ends of the list. Let 
X(I) be the reference number. In our example, this is 63. 

I J 
63 27 43 96 72 31 82 43 
Compare the two numbers indicated by the pointers and swap if 
necessary. 

I J 
43 27 43 96 72 31 82 63 
Move the pointer opposite the reference number one place 
towards it. 


| J 
43 27 43 96 72 31 82 63 
Repeat steps 2) and 3) until I= J. 
I J 
43 27 43 96 72 31 82 63 
! J 
45 27 43 96 72 31 82 63 
I J 
43 27 43 63 72 31 82 96 
' J 
43 27 43 63 72 31 82 96 
I J 
43 27 43 31 72 63 82 96 
I 
43 27 43 31 63 72 82 96 


When this stage has been reached the list has been split into two 
sub-lists. The reference number is now in its correct position in 
the list, and the sub-lists are the numbers to the left and right of 
this position. 


303 


5) One of the lists is stored for future sorting (see below) and the 
other is taken through steps 1 to 4 above. 


[43 27 43 31] 63 [72 82 96] 
mss, ee ee 
continue with store 
sub-list sub-list 
in correct 
position 
I J 
43 27 43 31 
I J 
31 27 43 43 
г J 


31 27 43 43 
New Sub-list 

[31 27 43) 

31 Zi 43 in correct 


position 
31 27 
27 31 43 
in correct 
position 


6) This process is repeated, in each case storing a sub-list where 
necessary, and finally going back and sorting all stored sub-lists 
so that eventually each number is in the correct position. 

The left-hand and right-hand numbers of a list are denoted by sub- 


scripts L and R respectively. 
The pointer positions are denoted by I and J and a flag S is set to 
indicate the pointer at the reference number, so that: 


S = 1 if reference number at pointer I 
S= – 1 if reference number at pointer J 


If at the end of step 4 the reference number is at I (as in our example) 
then the list has been split into: 


reference 
sub-list sub-list 
Es. uni l= I Пі, ... > X) 


The right-hand list is remembered by setting up a stack, using an array 
S (P,2) with P initially set to zero. As each sub-list is stored, we make: 


P=P+1 S(P,1)2I + landS(P,2)=R 


304 


The array S is initially dimensioned as S(X,2) for a list with X 
elements. P indicates the number of the sub-lists; S(P,1) the left-hand 
element and S(P,2) the right-hand element of the sub-list. In the 
example given, at step 5 we will have the first sub-list generated stored 
by setting: 


P = 1, S(P,1) = 6 and S(P,2) = 8 


Thus each list to be stored is placed in sequence into the array, this 
process being known as PUSHing on to the STACK. 

When the sub-list that the program continues with finally has only 
one number we must return to sort the stored lists. We retrieve a stored 


sub-list (POP a list out of the STACK) by letting: 
L=S(P,1),R=S(P,2)andP=P-1 
and continuing until all the lists are sorted. 


Program Listing 


= КЕМ "QUICK" 
10 PRINT "HOW MANY NUMBERS?" 
20 INFI'T X 
20 DIM A(X) 
40 DIM 5(Х,2) 
SO PRINT :*"INFUT NUMBERS" 
во ЕКПЕ N=1 TO X 
70 INFUT АСМ) 
Z0 NEXT М 
90 PRINT 
100 PRINT “UNSORTED LIST" 
110 FOR N=i TO X 
120 FRINT ACN" "3 
130 NEXT М 
140 PRINT 
LEQ REM же Ж ЖЖ ыы 3 
+ жж SORTING ROUTINE жж 
190 LET P=0 
200 LET L= 
210 LET R= 
Жә LET. Lim 
230 LET J= 
240 LET $= 
2 СІ = ACJ) THEN GOTO = 


270 LET ACD =ACN 
280 LET ACJ3I=T 


290 LET 5з-5 
200 IF S=1 THEN LET I=I+1 
ӘТО IP Sel THEN LET Ue Jed 


320 IF I<J THEN GOTO 250 

330 IF Ізі >= R THEN GOTO 270 
340 LET F=F +! 
350 LET S(P+1) 
360 LET 5Р2) 
370 LET RzI-1 


1 


i+ 
Е 


305 


280 IF L«R THEN GOTO 220 
290 IF Р=0 THEN GOTO 420 
400 LET L=icFs1) 

410 LET Е->2(Р.2) 

420 LET Ғ-Ғ-1 


4260 GoTo 290 


440 REM w* END OF SORT ++ 
3C 3c 3C 3€ 3C 3€ 363€ ЖЗ 

450 PRINT 

4&0 PRINT “SORTED LIST" 

470 FOR N-1 TO X 

420 PRINT ACNO:" "; 

490 NEXT N 

200 REM жж ЕМПРЕПС жж 


Lines 190 - 230 initialise P, and set values for L, R and the pointers 
I and J. 

Line 240 sets the flag which indicates the position of the reference 
pointer (S = - 1). 

Lines 250 — 290 make the interchange of A(I) and A(J) if necessary 
and reset the flag. 

Lines 300 — 320 move whichever of I and J is to be moved, according 
to how the flag is set. 

Line 330 checks if I is at the end of the list, bypassing the sub-list 
storage routine. 

Lines 340 — 360 ‘push’ sub-lists on to the stack. 

Lines 370 and 380 check if the sub-list has more than one element, 
sending control back to line 220 if it has. 

Line 390 sends control to the print routine if no sub-lists are stored. 

Lines 400 — 420 ‘pop’ sub-lists out of the stack. 

Line 430 starts the sort routine for the ‘popped’ sub-list. 


T7: Index Sort 


When data records or files contain several items (‘fields’) of 
information we often need to sort them according to one particular 
item. An index sort routine will enable us to do this. 

For example, we may have a series of records each containing a 
reference number, name, sex, age, home town and occupation: 


10 SMITH MALE 21 OXFORD BUTCHER 
20 JONES FEMALE 32 ENFIELD GROCER 


Each record contains six fields. We might wish to sort these records 
alphabetically by name (field 2) or numerically by age (field 4). A sort 
of the type presented here enables this to be done for any of the fields. 
Since it uses string arrays to hold records and performs an alphabetical 
sort it is necessary for all numerical items in any field to contain the 
same number of digits. We must hence use 010, 020, 100, 200 and not 


306 


10, 20, 100, 200, using leading zeros to maintain the value, but giving 
the same number of digits. 
The procedure is as follows: 


1. 


Set up an array N$ (N,L,C) containing N records, each of L 
fields with a maximum of C characters in any string. For 
example, we might use an array N$ (10,5,20), to represent 10 
records, each with 5 fields, which can each contain up to 20 
characters. 


Decide on the key field (i.e. the field you wish to sort) — say the Jth 
field. We must then set up an array K$(N,C) to store it, and let 
K$ (R) = N$ (R,]) for the number of records (FOR R = 1 to N) 
so that the list K$ (N,C) will then contain the items we wish to 
arrange in order. 


Sort the key field into ascending order. This is done in the 
subroutine starting at line 900 by counting how many times each 
element in the array K$ (N,C) is >= the other elements 
(including itself). ‘This sort uses a numerical array X(N) to store 
the result of this count (P) for each element, by setting X(P) to 
equal N, when K$(N) is the item being checked. 

We first set P = 1 (since each item is equal to itself) and then 
check through the other items of K$ (lines 920 to 970), making 
the count by letting P = P + 1 when the element is >= another 
element. If the elements are equal, the original order in N$ is 
kept (line 960): (i.e. test first element of K$ and set X(P) = 1, 
reset P, test second element of K$ and set X(P) = 2, etc.) 

For example, with 10, 30, 20, 40 as our K$ list, the array X(4) 
would hold the values: 


10 X(1)- K$ (1) 
30 X(3)= K$ (2) 
20 X(2)-KS$ (3) 
40 X(4)- К (4) 


Printing out K$ (X(1)) to K$ (X(4)) in order will give the sorted 
order of K$ elements. 


The array N$ (X (N), L, C) will now consist of the records 
sorted in the appropriate order, according to the field chosen, 
and is printed out using the loop variables R and I to access N$ 
(X(R), I) in lines 290 to 340. 


Program Listing 


5 КЕМ "INDEX" 
10 PRINT “SORTING RECORDS" 
20 FEINT »» "ТҮРЕ MAXIMUM NUMBE 
К OF CHARACTERS IN ANY ITEM" 


307 


30 INFUT C 
40 PRINT 33 "HOW MANY RECORDS?" 
SO INFUT М 
ео PRINT +, “HOW MANY ITEMS IN 
EACH RECORD?" 
70 PRINT 
Өө МЕЛТ L 
SE REN 333 3 Хы HH 
##INITIALISE $ ARRAYS ++ 
ЭО DIM ММУ Li; U) 
100 DIM K$6N3:0CO 
110 DIM ХОМ) 
120 REM 3333 5 ЖЕ EERE 
ЖЖІМРИТ RECORDS жж 
130 FOF Р-і ТОМ 
140 PRINT “ТҮРЕ "#15" ITEMS FOR 
RECORD "sk 
20 FOR Ісі TO L 
160 INFUT N$iE:I2 
170 NEXT I 
120 NEXT F 
190 PRINT 
200 PRINT "WHICH ITEM IS SORTIN 
G KEY?" 
210 INPLT J 
220 FOR Есі TON 
220 LET EKSCRI=NSCRy J) 
240 NEXT Е 
750 GOSE VOO 
260 PRINT 
270 FRINT “SORTED RECORDS ARE: " 
220 PRINT 
290 FOR Е=1 ТОМ 
200 FOR Ісі Tü L 
310 PRINT N$CXORD IOS" "5 
320 NEXT I 
220 PRINT 
240 NEXT Е 
220 PRINT 
260 PRINT "DO YOU WISH TO CONTI 
ММЕЗСҮ/М9" 
97/0 ¿NPUT Үз 
280 IF Y$-"Y" THEN GOTO 200 
390 STOP 


400 REM *##*#FROGRAM END жж 
3C 3t 3€ 3€ 3€ € € 3E € 9€ 9E 3€ 9€ C 3E 3E 3€ 3€ 9€ 3C 3€ 903€ 

ООо REM J39)t3 3 9 3 9€ X 9 9€ 963€ 9€ 9€ 96 3€ 3€ 9E 9E Ж 
##S0R TING SUBROUTINE «3 

700 FOR Асі TON 

S10 LET Pel 

720 FOR Е=1 TO N 

930 IF K$(ñ3:K$(E) THEN LET FF 


940 IF КФА) =КФСЕ) THEN GOTO 96 
750 GOTO 970 

760 IF АРЕ THEN LET Р=Р+1 

970 NEXT E 


950 LET ХҰРотА 
990 МЕХТ А 


308 


1000 RETURN 


1010 REM ** ENDSUE ++ 
ЗЕ ЗЕ ЗЕ HEHE ХАЖ 


For example, if we input a storage array of £ records with 3 fields, 
maximum 6 characters in any item, and use as input data: 


SMITH, 460, OXFORD 
JONES, 080 LEEDS 
BROWN, 730, YORK 
WHITE, 095, BATH 


Results are as follows: 
(1) Using field 1 as key 


Sorted records are: 


BROWN 730 YORK 
JONES 080 LEEDS 
SMITH 460 OXFORD 
WHITE 095 BATH 


(п) Using freld 2 as key 


Sorted records are: 


JONES 080 ^ LEEDS 
WHITE 095 BATH 
SMITH 460 OXFORD 
BROWN 730 YORK 


(ш) Using field 3 as key 


Sorted records are: 


WHITE 095 BATH 
JONES 080 LEEDS 
SMITH 460 OXFORD 
BROWN 730 YORK 


T8: Linear Search 


The most straightforward way of looking for a particular number in a 
list of unsorted numbers is to examine the list one by one in each case 
comparing with the *wanted' number. 

In this program a set of random numbers is created between 100 and 
199 and it is arranged so that there is only a single occurrence of each 


309 


number. This is in lines 40-60. The list is printed out in lines 
70-110. The search routine is then carried out in lines 200 — 300. 
Clearly a number near the beginning of the list is found quickly but one 
at the end rather slowly. For a 5@ element list the average number of 
searches will be 25. 


5 REM "SEARCHI" 
10 DIM A(100) 
15 PRINT "TYPE NUMBER <100" 
20 INPUT N 
30 IF N»100 THEN GOTO 15 
40 FOR M=] TO N 
50 LET A(M)=INT (1ØØ*RND) +100 
52 FOR R=1 ТОМ-1 
54 IF A(M)=A(R) THEN GOTO 50 
56 NEXT R 
60 NEXT М 
70 PRINT "UNSORTED LIST" 
80 FOR M=1 TO N 
90 PRINT A(M);" "; 
100 NEXT M 
110 PRINT 
200 REM **LINEAR SEARCH** 
210 PRINT "TYPE NUMBER BETWEEN" 
220 PRINT "100 AND 199" 
230 INPUT X 
249 FOR I-1 TO М 
250 IF X=A(I) THEN GOTO 300 
260 NEXT I 
270 PRINT "NUMBER NOT IN LIST" 
280 PRINT "AFTER ";N;" SEARCHES" 
290 GOTO 400 
300 PRINT "NUMBER ";X;" AFTER "; 
I;" SEARCHES" 
400 REM **END** 


T9: Binary Search 


This is a much faster search technique than the linear search but can 
only be used for a list that has already been put in order. In many 
applications you will be dealing with an ordered list and under such 
circumstances this is the appropriate method to use. 

In the program the binary search technique is in lines 500 to 600. 
The basic idea is to compare the wanted number with the middle item 
of the ordered list. The wanted item is then either smaller (in which 
case we know it is in the first half of the list) or larger (in which case it is 
in the second half of the list) than the middle item, unless it is equal to 
it-in which case we have completed our search. The process is 
repeated, in each case halving the list. Consider a search for 30 in the 
following list: 


l 2 4 6 8 10 12 14 16 18 20 24 28 30 36 


We first choose 14 (middle). 


310 


Our list is now: 


16 18 20 24 28 30 56 


and we choose 24 (middle). 
Our list 1s now: 


28 30 36 


We select 30 (middle). 

Thus we have found the number in three searches (compared with 
fourteen using the linear search). 

In the program the following sections occur: 


(1) Setting up initial unordered list and printing out (lines 
10 — 150). 
(ii) Sorting this list into order and printing it out (lines 200 — 330). 
(ш) Binary search with printout (lines 500 — 680). 


5 REM "SEARCH2" 

10 DIM А(50) 

20 PRINT "TYPE NUMBER <50" 

30 INPUT N 

40 IF М>50 THEN GOTO 20 

50 FOR M-1 TO N 

60 LET A(M)=INT (100*RND)+100 
70 FOR R=1l TO M-1 

80 IF A(M)-A(R) THEN GOTO 60 
99 NEXT R 

100 NEXT M 

110 PRINT "UNSORTED LIST" 

120 FOR M-1 ТОМ 

130 PRINT A(M);" "; 
140 NEXT M 
150 PRINT 
200 REM **{NSERTION SORT** 
210 FOR Ізі ТО N-1 
220 LET J-I 

230 LET T=A(I+1) 

240 IF T»-A(J) THEN GOTO 280 
250 LET A(J+1)=A(J) 
260 LET J=J-1 
270 LET J»-1 THEN GOTO 240 

280 LET A(J+1)=T 
290 NEXT I 
295 REM ***ENDSORT*** 
300 PRINT "SORTED LIST" 

310 FOR M-1 TO N 

320 PRINT A(M);" "; 

330 NEXT M 

340 PRINT 

350 PRINT "TYPE NUMBER REQUIRED" 
360 PRINT "BETWEEN 100 AND 199" 
370 PRINT "TO FINISH TYPE 999" 
380 INPUT X 

390 IF X-999 THEN GOTO 709 
400 PRINT 


311 


Results: 


410 


500 
510 
520 
530 
540 
550 
560 
570 
580 
590 
600 
610 
620 
630 
640 
650 
660 
670 
680 
690 
700 


PRINT "SEARCH ";N;" ITEM LI 
ST" 


REM **BINARY SEARCH** 
LET L=l 

LET H=N 

LET С-О 

LET M=INT ((H+L) /2) 

LET С=С+1 

IF X=A(M) THEN GOTO 630 
IF L>=H THEN GOTO 660 
IF X>A(M) THEN GOTO 610 
LET Н-М-1 

GOTO 540 

LET L=M+1 

GOTO 540 

PRINT "NUMBER FOUND ";X 
PRINT "AFTER ";C;" SEARCHES" 
GOTO 350 

PRINT "NUMBER NOT FOUND" 
PRINT "AFTER ";C;" SEARCHES" 
GOTO 350 

REM **END SEARCH** 

REM **END** 


TYPE NUMBER «50 

UNSORTED LIST 

117 118 101 189 
188 197 172 106 
130 181 100 165 
155 167 199 138 
113 143 154 194 


106 107 111 113 
128 130 131 133 
148 150 Loo 154 
165 167 168 172 


144 128 
150 107 
168 160 
186 190 
131 142 
SORTED LIST 
100 101 
119 122 
143 144 
160 163 
186 188 


189 190 194 197 
TYPE NUMBER REQUIRED 
BETWEEN 100 AND 199 

LO FINISH ТҮРЕ 999 


SEARCH 40 ITEM LIST 
NUMBER FOUND 198 
AFTER 5 SEARCHES 


T10: Storing a List 


We can store data in an array for use in a program via INPUT loops 
when there is more data to be inserted than we care to put directly in 
the program using LET instructions. There are programs in the text 
that use this technique (e.g. “ЕГЕМЕМТ”). To illustrate the 


214 


111 
127 
175 
122 
119 


117 
138 
155 
175 
198 


198 
148 
133 
163 
153 


118 
142 
157 
181 
199 


technique, here is a simple example that doesn't require you to INPU T 
anything. Key in and run the first program to create A(N) and fill it 
with random numbers. Edit the program, replacing the original lines 
with those of the second program. SAVE this program. LOAD it back 
in. If we used RUN it would clear all the variables, and wipe out the 
array we have stored. 

Program execution must be started with a GOTO statement, in this 
case GOTO 10. The array will then print out. 


10 DIM A(40) 

20 FOR N=1 TO 40 

30 LET A(N)=INT (100*RND)+100 
40 NEXT М 


10 REM "SAVED*ARRAY" 

20 REM **EXECUTE PROGRAM** 

30 REM **USING GOTO 10%% 

40 PRINT "LIST OF RANDOM NUMBERS" 
50 PRINT "BETWEEN 100 AND 199" 

60 FOR N-1 TO 40 

70 PRINT A(N) 

80 NEXT N 


So this 1s the general procedure: 
(1) Write an array creation program and run it, i.e. A(N) created 
and data inserted. 
(2) Edit out lines and put in additional lines as required. 
(3) SAVE the final program. 
(4) LOAD program and execute using a GOTO statement. 


To avoid the possibility of the user entering RUN, we can use a 
structure which automatically initiates the program on loading. The 
program below for the ZX81 also illustrates the fact that one may use a 
string variable as a program name. 

Lines 10 to 80 create array and have the input routine. These lines 
could be edited out as soon as the data was input, or left in to enable 
(through the use of RUN) a different set of data to be input. 

Line 90 onwards are the program to use the stored data. 

Line 9010 requests a string input to be used as the program name. 
9020 gets the string, and 9030 and 9040 give you the chance to write it 
down before you forget. 

9050 waits for a key to be pressed, and 9070 saves the program and 
its variables. One of these variables stores the line the computer had 
got to in the program, and when loaded back it starts where it left off 
(9070) and goes to line 90 automatically. 

10 REM **AUTO-RUN ROUTINE** 

20 REM AUTOMATIC RUN WILL 
PRESERVE VARIABLES 

30 REM AVOID STATEMENTS 
OR EDIT THEM OUT. 

40 REM ***DIMENSION/INPUT, ТО 
STORE VARIABLES *** 


50 DIM А(20) 
60 FOR F-1 TO 20 


313 


70 INPUT А (Е) 
80 NEXT F 

90 PRINT "PROGRAM TO USE DATA" 
100 FOR F=20 ТО 1 STEP -1 

110 PRINT A(F) 


120 NEXT F 

130 REM ...... MORE PROGRAM 
140 REM ....... 

8990 REM **SAVE AND AUTO-RUN** 
9000 CLS 


9010 PRINT "INPUT PROGRAM NAME" 

9020 INPUT AS 

9030 PRINT "PROGRAM NAME:";A$ 

9949 PRINT "READY TO SAVE.NOTE P 
ROGRAM NAME.PRESS A KEY TO 
SAVE PROGRAM","AFTER SETTI 
NG CASSETTE TO RECORD*****" 

9050 IF INKEYS="" THEN GOTO 9050 

9060 CLS 

9070 SAVE AŠ 

9075 REM **GOTO LINE AFTER DIM/ 
INPUT ROUTINE IF NOT EDITED 
OUT kk 

9080 GOTO 90 


The Spectrum has an automatic message and built in wait-for-key- 
press routine. It also has an automatic run-after-LOAD facility. If a 
line is entered in a program of the form: 


9000 SAVE ‘‘program’’ LINE 200 


and the program is saved with a GOTO 9000, the program will start 
running after loading by going to the line stated (200 in the example). 
For the Spectrum, this program needs modifying by deleting lines 
9070, 9075, 9080, changing 9040 to read PRINT*'NOTE 
PROGRAM МАМЕ”, 9050 to PAUSE 0, and 9060 to SAVE 
A$ LINE 90. 


T11: Storing a String Array 


The ZX81 program PRETTY draws a picture on the screen (slowly!) 
which is stored in the array A$, dimensioned in line 100. If this 
program is run the array A$ is created, and the screen display stored, 
character cell by character cell, in A$. The lines in the program can be 
edited out so that finally we have a program like PRETTY2. This may 
be SAVEd and includes the created array A$. To execute the program 
PRETTY2 after loading we must use GOTO 5, to avoid the use of 
RUN, which clears all arrays (and hence A$) before execution starts. 
5 REM "PRETTY" 

10 FOR J-1 TO 19 

20 FOR N=ø TO J*12 

30 PLOT 32-27%2%5ІМ (N/(J*6)*PI), 

224J*COS (N/(J*6)*PI) 
40 NEXT М 
50 NEXT J 


314 


100 DIM A$(704) 

110 FOR I=0 TO 21 

120 FOR Ј=1 TO 32 

130 LET A$(J+32*I)=CHR$ PEEK (PEEK 
163964256*PEEK 16397-4J-433*I) 

140 NEXT J 

150 NEXT I 


5 REM "PRETTY2" 
10 PRINT A$ 


Notice that we have stored the screen display in the array. 

Check you understand the process of PEEKing the display file. 

The Spectrum stores a screen display using a special form of SAVE. 
This has the form: SAVE “РКЕТТҮ” SCREENS, where PRETTY 
can be any name. This is loaded back using LOAD “РКЕТТҮ” 
SCREENS. 

Try this procedure on your Spectrum. The program above can be 
revised for the Spectrum. Enter just the following lines: 


10 FOR J=1 TO 40 STEP 4 
20 FOR N - 0 TO J*12 STEP 4 

30 PLOT 125 + J*2*SIN(N/(J*6)* PD,88 + J'COS(N/(J*6)*PI) 
40 NEXT N 

50 NEXT J 


Use SCREENS to save the picture as above. To continue with screen 
displays, the Spectrum can store a screenful of characters in much the 
same way as the ZX81 program above, using SCREENS to access each 
character in turn, placing them in sequence in array A$(704). A 
screenful of characters is generated at random, using the single 
characters from the Spectrum character set, placing these along each 
line. 

The double loop (lines 60 to 100) uses SCREENS (F,N) to check 


each character along each line, placing it in the array A$. 


= DIM 4$(7042 

10 FOR F=0 TO 21 

20 FOR NzO TO 31 

30 PRINT АТ F:N? CHES (32+ ЕМІ 


#97) 
40 NEXT N 
SO NEXT F 


ео FOR Ғ-о Tü 21 

70 FOR М-о ТО 31 

SO (ЕТ AS(N+14+32#F3=SCREENS 
СЕ» № 

70 NEXT N 

100 NEXT F 


Now edit out all the lines, replacing 5 with 5 PRINT A$, and RUN the 
program using GOTO 5. 


315 


The same program for the ZX81 needs to use PEEK to access the 
display file, just as in “РКЕТТҮ”. Replace lines 5 to 50 in 
“PRETTY” with the following, to print a random set of ZX81 


characters on the screen: 


5 КЕМ "SCREENFULL " 

10 FOR F=1 TO 704 

20 PRINT СНЕФ INT ( REND #54); 
30 NEXT F 


The same principle holds good for any string array or numeric array. 
Once the program has been run and the data inserted into the array, 
the data is safe as long as RUN is not used again, and can be accessed 
as required. The ELEMENT program treated in Unit W3 uses this 
procedure to store data required in the program. 


Exercise 


Write the appropriate array creation program for the following 
program: 


10 REM "SAVEI10" 

20 REM **THIS PROGRAM MUST BE** 
30 REM **EXECUTED USING GOTO10** 
40 PRINT “MONTHS OF THE YEAR" 

50 FOR N-1 TO 12 

60 PRINT M$ (N) 

70 NEXT N 


T12: Storing Data in Strings 


Strings can be used to store data, which may be accessed using the 
string-handling instructions. The data can also be re-assigned, or new 
values inserted. Numbers may be used, the STR$ and VAL 
instructions enabling conversion from numbers to strings and vice 
versa. 

The first example has the data stored in A$. The names of the 
months are all three letters long, and can thus be accessed using the 
simple numeric calculation of line 70. 

10 REM STRING DATA STORE 

20 REM *AS HAS DATA* 

30 LET A$="JANFEBMARAPRMAYJUNJ 
ULAUGSEPOCTNOVDEC" 


40 REM *DATA INPUT* 

50 PRINT "INPUT MONTH(1 TO 12) 
н 

60 INPUT MONTH 

70 PRINT "MONTH ";MONTH;" IS " 
;AS(MONTH*3-2 TO MONTH*3) 


316 


The next program has the full names of the months, with varying 
lengths. Full stops are used to make the principle clear, but spaces 
between the months would be used in a practical program. (As it is, a 
full stop is printed after the month, rather than the useful space.) The 
program stops the search after the required month has been found (line 
100), but is a little slow on the ZX81 unless FAST is used (line 65). 


10 REM STRING DATA STORE 

20 REM *AS HAS DATA* 

25 REM **USE SPACES,NOT FULL S 
TOPS IN REAL PROGRAM** 

30 LET AS=".JANUARY. FEBRUARY.M 
ARCH. APRIL.MAY.JUNE. JULY. AU 
GUST. SEPTEMBER. OCTOBER. NOVE 
MBER. DECEMBER," 

40 REM *DATA INPUT* 

50 PRINT "INPUT MONTH(1 TO 12) 
" 


60 INPUT MONTH 

65 FAST 

70 LET P=0 

80 LET A-1 

90 IF AS(A)="," THEN LET Р=Р+1 

100 IF P=MONTH+1 THEN GOTO 140 

110 IF P=MONTH THEN PRINT AS (А+ 
1); 


150 PRINT "IS THE MONTH INPUT" 


Spectrum users should, of course, delete the FAST and SLOW 
instructions, lines 65 and 140. 

The next program uses a string to store numeric data. The numbers 
are input, and placed in the string as the STR$ string plus ‘‘*’’, which 
is used as an indicator. The data is retrieved by using the subroutine 
(at line 1000) to step through each number string in turn, returning the 
number string as Z$ when RETURN is executed on an asterisk being 
found (line 1020). The two data access routines (lines 110 to 140 and 
150 to 180) after the initialisation of NSTRING could occur anwhere 
in the program. The data can be accessed in an order by suitable 
manipulation of the access instructions (e.g. the reverse loop in lines 
150 and 180), and NSTRING can be re-initialised as zero at any point. 
Counting loops could be used to access an Nth item of data. 

Spectrum users should note that the Spectrum has READ and 
DATA functions (which are dealt with in Section W), that provide a 
more convenient way of storing and retrieving data for many 
applications, but are less flexible than string storage in some cases, 
especially when used as illustrated below. DATA items must be keyed 
in within the program listing and cannot be input. 

5 REM *INITIALISE* 


10 DIM A(10) 
20 LET А5-"" 


317 


REM *DATA INTO STRING* 
FOR Е-1 TO 10 

INPUT NUMBER 

LET А$=А$+5ТА$ NUMBER+"*" 
NEXT F 

REM ....... 

REM ....... 

REM ....... 

REM *RESTORE START* 
LET NSTRING=0 

FOR Е-1 TO 5 


GOSUB 1000 

LET A(F)=VAL ZŠ 

NEXT F 

FOR F=10 ТО 6 STEP -1 


GOSUB 1000 

LET A(F)=VAL Z$ 

NEXT F 

РРР 

MEN жола» 

ЅТОР 

REM ***READ STRING SUB*** 
LET Z$-"" 

LET NSTRING=NSTRING+1 

IF AS(NSTRING)="*" THEN RET 
URN 

LET Z$2Z$4A$ (NS TRING) 
GOTO 1010 


318 


SECTION U: THE COMPUTER MEMORY 


U1: Memory Organisation 


Digital computers operate with sequences of numbers in the binary 
number system. Binary numbers are numbers to base 2, and our 
‘normal’ number system is decimal (base 10). 


The BINARY system uses only two digits, 0 and 1. These are 
binary digits (bits). The computer holds a bit as a voltage level 
( + 5v or Ov) іп a switched pathway. 


In the decimal system, a number, for example 418, is coded as a number 
using the digits @ to 9. The coding is based on powers of ten. 418 
means: (4 times 10 to the power 2) +(1 times ten to the power 1) + (8 
times ten to the power 0). 


(4x 10” + (1x10) + (8х 10’) 
400 + 10 + 8 = 418 


The binary system of coding uses powers of two in exactly the same 
way. 
The number 13 is represented as: 


(1x 2") + (1x27). € (0x2) + (1x2? 
1 1 0 1 Binary number 1101 
8 + 4 + 0 + 1-13 Decimal equivalent 


The binary number 101110 is evaluated as: 
(1 x 27) + (0 x 2) + (1x 2°) + (1 x 2”) + (1 x 2)) + (0 x 2^) 
32 + 0 2,2%. Ü 


+ 8 + 4 + = 46 in decimal 


Key in the following program, which converts decimal numbers to 


their binary representation: 
1 REM *DECBI* 
2 REM CONVERTS DECIMAL TO 
BINARY NUMBERS 
10 PRINT “ENTER DECIMAL NUMBER 
20 INPUT N 
30 PRINT М; 
40 LET BS="" 
50 LET L=INT (N/2) 
60 LET BzN-2*L 
70 IF B=1 THEN LET А5-"1" 
80 IF B=@0 THEN LET AS="9" 
90 LET BS=AS+BS 
100 LET N=L 
110 IF L>@ THEN GOTO 50 
120 PRINT " IS ";В5;" IN BINARY" 


Input sequences of numbers to familiarise yourself with the binary 
system. The program only deals with positive whole numbers. Trace 


319 


the progam to see how it works, using the examples 13 and 46 given 
above as inputs. Non-integer numbers are dealt with by using an 
exponent, as with the E notation system for decimals. Binary numbers 
have a binary point, and bits to the left of the point are binary fractions, 
representing the reciprocal power of two. The binary number 1.101, 
for instance, represents: 


GN FEM pe 
(1x2) + (91) +( 9) + (93) 
1 + 5 + 0 + .125 -1.625 


You may have noticed that binary numbers as seen above are all 
positive. Negative numbers are dealt with by using a particular form of 
binary representation. The method by which the ZX81 and Spectrum 
store numbers is described later in this Section. 

In a computer, numbers are held in fixed numbers of bits. These are 
referred to as words. 


A BYTE is a sequence of 8 bits. The sequence of 8 bits 
represents a number between 0 and 255 decimal, 00000000 
and 11111111 binary. The ZX81 and Spectrum use 8 bit 
words, i.e. 1 byte. 


Memory in computers is organised as a linear sequence of addresses. 
Each address is a memory location or memory cell holding a single 
byte. The binary numbers in these locations are interpreted as 
numbers, characters or instructions depending on their context in the 
computer memory. The organisation of the memory is constant, but 
the space occupied by each area of memory varies according to the 
program and its requirements. As an obvious example, a long program 
takes up more space for storage than a short one. 


Memory is of two types: 

READ ONLY MEMORY (ROM) is fixed and cannot be 
altered. It contains the BASIC interpreter program, and is 
built-in to the computer in manufacture. 

RANDOM ACCESS MEMORY (RAM) is variable, multi- 
purpose memory that holds the current program and all the 
other elements of data required to run the program. 


Data can only be extracted from ROM (‘read’), and is permanent. 
RAM memory can be both read from and written to. Inserting a value 
into a memory location in RAM (writing or storing) will wipe out or 
overwrite the existing data at that address. 

Memory capacity is referred to as the number of Kilobytes (k) 
involved. Kilo refers to one thousand, but this is only approximately 
true, since a kilobyte is actually 1024 (2”) bytes. The ZX81 has 8k of 
ROM memory and, with the memory expansion, 16k of RAM. The 


320 


Spectrum has 16k of ROM and either 16 or 48k of RAM. The memory 
is organised as shown in the diagrams below (called memory maps). 
The ZX81 and Spectrum have somewhat different memory 
organisations. We will deal first with the ZX81, and then the 
Spectrum. Spectrum users should read through the ZX81 section, 
however, as definitions of the functions of various types of memory are 
covered in this Unit. 


ZX81 MEMORY МАР 


Address Contents 


32767 
GOSUB STACK 
















Unused addresses. No memory 


16509 


16384 


space exists for this area. 
8192 





ROM memory area. BASIC 
interpreter and operating 
system program. 
0000 
Тһе top of memory (КАМТОР) is usually вес ав shown оп switch-on, 
at 32767. The computer can be instructed to set RAMTOP at some 
lower value, to leave spare memory locations which can be used to 
store machine code programs, which are called (like subroutines) from 
the BASIC program with the USR instruction. Machine-code 
programming is outside the scope of this text. 

Some areas of memory are organised in the form of a stack. This is a 
system such that the last item entered will be the first to be pulled off 


321 


the stack. A number may only be placed on the top of the stack of 
existing numbers, and the only accessible number 15 the one on the top. 
This creates an ordered sequence. In the GOSUB stack this is used to 
ensure that the RETURN instructions are followed in correct 
sequence. Each GOSUB instruction causes the following line number 
to be added to the stack. RETURN then takes the first line number off 
the stack to get the correct line number to pass control of the program 
back. 

The machine-stack memory area is used to keep track of the 
operation of the program. The spare memory area is that portion of the 
allocated area not occupied by the program and other memory areas. 
Although we referred to the top of the stack, it is more correctly the free 
end of the stack on to which the numbers are placed. The free end of 
the machine stack is at the bottom, in terms of the memory address 
sequence, hence the spare memory is below the machine stack in our 
diagram. 

The calculator stack is used for arithmetic operations. The work 
space holds the program line being input and provides temporary 
storage for data being manipulated ~ a scratch pad. 

The variables area stores all variables initialised in the course of a 
program. They are held in various forms, and we shall deal with the 
way numbers and variables are stored in the next Unit. 

The display file has been covered in Section O. The program area 
contains the program lines. This area always starts at address 16509. 
All other memory areas ride on top of the program area, moving up or 
down as the program lengthens (has program lines added or inserted) 
or shortens (has lines deleted), apart from the GOSUB and machine 
stacks, which are always at the top of memory. 

The systems variables area holds the special variables which store 
information concerning the state of the computer for use by the 
operating system. Certain of the system variables were introduced in 
Section Q. Like the D-FILE system variable introduced there, some of 
these variables hold the addresses of the divisions between the areas of 
memory. Other variables hold values of addresses, line numbers, 
characters, etc., to keep track of what state of affairs is current in the 
operating system. You have seen, for instance, that the DF-SZ variable 
stores the number of lines on the lower part of the screen. Some other 
system variables are dealt with in the next Unit. There are a fixed 
number of system variables, and their values are always held at known 
addresses between 16384 and 16508. The names of the system 
variables are not recognised as BASIC variable names, but are just 
mnemonics for the system variable function. 

On the ZX81 there is no memory corresponding to addresses 
8193-16383. Addresses 0 to 8192 contain the system software in ROM 
which holds the BASIC interpreter and operation program in machine 
code. 


322 


SPECTRUM MEMORY MAP 
Address Contents 


32767 (16k) 
USER DEFINED GRAPHICS 


65535 (48k) 


ROM AREA. BASIC INTERPRETER 





RAMTOP 









RAM 







23734 






23552 






23296 






22528 






16381 







AND OPERATING SYSTEM PROGRAM 





0000 


The memory тар of the Spectrum memory is somewhat different from 
that of the ZX81. The Spectrum also comes in two versions, one with 
16k of RAM, one with 48k. The ROM is also larger on the Spectrum, 
occupying 16k. Thus the first 16k of memory addresses (0000 to 16383) 
are occupied by ROM on the Spectrum. A 16k version then has the 
next 16k of memory as RAM, up to address 32767. The 48k Spectrum 
uses addresses 32768 to 65535 for the additional RAM memory. Apart 
from the size of memory, the arrangement of memory is the same in 
both Spectrum versions, as shown on the diagram. The fixed memory 
points are given as the memory address. 

The Spectrum memory requires more separate areas (reserved for 
the additional functions of the Spectrum), and the organisation is 
somewhat different. Working from the top of memory down, we notice 
an area set aside for user-defined graphics. This occupies 168 bytes, 


323 


and is set at the actual top of the memory, which is referred to as 
Physical RAM TOP. The bottom of the user-defined graphics area is 
the RAMTOP that the computer recognises as the top of memory. 
This leaves the user-defined graphics area protected from any 
interference by the operating system. On switch-on, the address of 
RAMTOP is thus set at 65367 with a 48k Spectrum, 32599 on a 16k 
version. This is the memory address of the last existing byte of memory 
before the user-defined graphics area. Below this are the GOSUB stack 
and the machine stack, with the area of free memory below this, as on 
the ZX81. 

The calculator stack, work space for lines being keyed in or data 
being processed, and the variables storage area are all in the sequence 
followed by the ZX81 memory. Then we have a significant difference 
between the two memories. The display file on the Spectrum 15 fixed, 
and does not appear above the program area, but at the bottom of 
RAM. Between the program area and the display file are Spectrum- 
specific areas, concerned with input and output and colour. The 
channel information area has information required for the operation of 
the printer, the keyboard, and the ТУ screen in terms of its division 
into top and bottom screens, the bottom one expanding if necessary to 
contain the required lines. This area is adjacent to an area of memory 
that will be used to store data necessary for the operation of the Sinclair 
microdrive disc system when it becomes available and is attached to a 
Spectrum. This area ‘vanishes’ without the microdrive and there is no 
sequence of memory bytes allocated to it. This area begins at address 
23734. Without the microdrive, this address becomes the start of the 
channel information area. 

System variables occupy 182 bytes of memory, from 23552 to 23733 
inclusive. The printer buffer on the Spectrum is larger than that on the 
ZX81 because of the need to store information about each of the 8*8 
points in a character cell (where the ZX81 only needed to store 
character codes). The buffer, to store a full line for the printer, needs 
256 bytes. This is because each line of points іп а 32 character line 
needs 8*32 bits, and there are 8 of these lines needed to make up a line 
on the printer. This buffer occupies the bytes from 23296 to 23551 
inclusive. 

The colour attributes (see Section W for this) occupy one byte per 
character cell, so the storage is 24*32 bytes from 22528 to 23295. These 
store the information about the colour (background and printing 
colour), brightness and flashing characteristics of each PRINT 
position. This information, together with the display file, determines 
the screen display. The display file holds the information about the 
pattern of dots to be placed on the screen, and the attributes file the 
additional data for a colour display. The display file occupies the 
memory addresses from the start of RAM (16384) to 22527. This is 
6144 bytes, so we can note that on a 16k Spectrum some 42% of RAM 
is needed for the display and attributes files only. This leaves about 9k 


324 


for program and operating areas, and illustrates the fact that high- 
resolution graphics take up large amounts of memory. 

Below 16384, the memory addresses are all ROM memory. The 
more complex operating system of the Spectrum demands more 
Instructions in ROM than are required by the ZX81. There is no gap 
in memory at all on the 48k machine, all 64k of memory that the Z80 A 
chip (the central processing unit) can address being used. On the 16k 
Spectrum, of course, the memory addresses above 32767 are unused. 


U2: PEEK and POKE 


The PEEK and POKE instructions have been introduced for specific 
purposes in connection with the display file and character storage. This 
should have given you some understanding of their uses. Now that you 
have been introduced more generally to the way memory is stored in a 
computer, you will notice that these instructions provide direct access 
to the memory of the computer. 


PEEK N returns the value (in decimal notation) of the 
number stored in binary form in the memory byte of address 
N. In the ZX81, N must be in the range @ to 8192 to return 
the contents of ROM memory, and in the range 16384 to 
32767 to return the contents of RAM. For the Spectrum, 
ROM extends from @ to 16383, RAM from 16384 to 32767 
(16k version) or 65535 (48k version). 


POKE M,N places into the memory address M the binary 
form of the decimal number N. N must be in the range @ to 
255 (to fit in a single byte). For the ZX81, and 16k Spectrum 
M must be in the range 16384 to 32767. The 48k Spectrum 
uses addresses up to 65535. ROM may not have values 
POKEd into it. 


In general, we use PEEK to extract from memory any values useful to 
our program, and POKE to insert values into memory. Remember 
that the values (entered and returned in decimal notation) can be 
numbers, characters or instructions. Machine-code programming is 
performed by POKEing into a specified sequence of addresses the 
values which correspond to instructions which the 780 central 
processor chip understands. This sequence of instructions is then called 
from within a BASIC program, in a similar fashion to calling a 
subroutine, and is executed. At the end of the machine-code program, 
a return instruction passes back control to the BASIC program. 

We will use PEEK to investigate how numbers and program lines 
are stored in the ZX81 and Spectrum. Different types of number have 
different formats in which they are held. The normal number in 


325 


memory is held іп 5-5yte floating роті binary form. Each number is stored 
in 5 bytes of memory. 

The (те numbers in a program are stored in 2 bytes of memory. 
Numbers in a program listing are stored as their printed characters, 
then in 5-byte form. 

Enter the program below if you are using a ZX81. It PEEKs the 
memory locations from address 16509 onwards, 1.e. each address in 
memory from the start of the program listing, after printing out the 
numbers as instructed in the first three lines, and prints the address, 
contents of the address as a decimal number, and the character string 
corresponding. The corresponding program and output for the 
Spectrum is given after the ZX81 has been dealt with, since the 
character codes are different. 

5 REM "PROGLIST" 
10 PRINT 23 
20 PRINT 123E8 
30 PRINT 123E-8 
40 LET A=16509 
50 PRINT A;TAB 10;РЕЕК A;TAB 1 
5;CHR$ (PEEK A) 


60 LET A=A+1 
70 GOTO 50 


You will get a display (use COPY to get a printer listing, and CONT to 
continue) that looks like this: 


23 

19300000000 
1.23E-65 

165809 e 
16510 ла = 
16511 ла ж 
16512 e 
16513 245 PRINT 
16514 зе 2 
16515 93. 5 
16516 126 7 
16517 153 Е 
15518 56 5 
16519 а 
15520 ә 
15521 

15522 1:5 * 
16523 

16524 го - 
16525 13 E 
16526 

16527 245 PRINT 
16528 29 1 
16529 3@ 2 
16530 зі З 
16531 42 Е 
16532 зе 8 
16533 126 2? 
16534 ie2 B 
16535 55 R 
16536 72 7 
16537 198 LE? 
16538 192 " 
16539 118 7 
16540 

16541 зе 2 
16542 14 
16543 

16544 245 PRINT 
16545 29 1 
16546 за 2 
16547 gi 2 
16548 42 E 
18549 22 - 
16558 зе в 
16551 126 ? 
16552 199 7 


16553 27 9 
15554 22 = 
163553 122 = 
16556 le? Ф 
15557 118 Y 
16558 e 
16559 406 с 
16562 15 = 
16561 

16562 241 LET 
16563 A 
16564 20 = 
163565 29 1 
165656 3d & 
1655? 33 5 
i6568 2o e 
155692 з” 9 


Notice first the way the ZX81 changes the format of the numbers. 23 
prints as 23, but 123E8 is printed as 12300000000, and 123E-8 as 
1.23E-6. The operating routines put each number into a standard 
format for printing to the screen. In order to present a listing of the 
program, which is what you’ve typed in, the computer must hold two 
forms of the number; first the literal characters and second the 5-byte 
floating point form. 

Inspect the printout from the program. The first address printed is 
16509, holding zero. This is the first of the two bytes holding the line 
number. Notice that the more significant byte comes first. This is the other 
way round from normal 2-byte values (those of the system variables, 
for example). Since the line number is less than 255, the first byte holds 
zero and the second (16510) holds 10. 

16511 holds 10 again. This is the number of characters in the line. 
16512 has zero, since these two bytes hold the line number as (First 
byte value) + 256* (Second byte value), in the standard way. 

16513 holds the value 245, representing the keyword character 
PRINT. Then come the characters 2 and 3 (codes 30 and 31). Bytes 
16516 to 16521 hold the values 126, which indicates that the next 
sequence of bytes holds a number, and then 133,56,0,0,0. This is the 
5-byte form of 23. We shall see in the next Unit the mechanics of this 
way of representing numbers. 

Check through the rest of the listing and make sure that you 
understand how and why the memory addresses contain the values 


they do. 
SPECTRUM PROGRAM LISTINGS 


The program below for the Spectrum has a different form from that for 
the ZX81. This is a consequence of the strange results of the control 
characters in the Spectrum character set if used as a CHR$ (see Unit 
P2). We must avoid using a PRINT CHR$ instruction for these 
control characters. The program sets a logical condition to test the 
value of A in lines 60 and 70 which prints “CONTROL CHR” 
instead of the CHR$ form if the printing of the CHR$ would cause 


problems. 
10 PRINT 23 
20 PRINT 123E8 
30 PRINT 123E-8 


327 


40 LET A=(PEEK 23635+256*PEEK 
23636) 

50 PRINT A;TAB 10;PEEK A;TAB 1 
5; 

6@ IF РЕЕК A>23 OR PEEK A<15 T 
HEN PRINT CHR$ (PEEK A) 

70 IF PEEK А<-23 AND PEEK A>=1 
6 THEN PRINT “CONTROL CHR" 

80 LET A=A+1 

90 GO TO 50 


The results will be as follows. (Use scroll to see the full listing. To get a 
printout like the one here, you must BREAK the program when 
“Scroll?” appears, then use COPY, then CONT to get the next 
screenful.) 


1.2ЗЕ +19 
1.23E-6 

23755 e ? 
23756 10 > 
23757 10 ? 
23758 ә ? 
23759 245 PRINT 
237862 Ea 2 
23751 51 3 
23762 14 > 
BATES © s 
23764. e ? 
257855 23 CONTROL CHR 
23756 e > 
23767 e т 
23768 13 

23752 e ? 
23770 го CONTROL CHR 
25771 13 

patya © “y 
23773 245 PRINT 
2377 49 1 
23775 sa 2 
23776 51 3 
597727 вә Е 
23778 56 а 
23779 14 ? 
23780 162 5 
23781 =s ? 
23782 72 H 
23783 198 AND 
23784. 192 USR 
23785 13 

23786 ә т 
237857 зә Е: 
53788 14. % 
23789 © ? 
23720 245 PRINT 
23791 49 1 
23792 sa 2 
53793 51 5 
23794 БӘ Е 
23795 45 m 
23796 56 a 
23797 14. ? 
23798 189 ш 
23799 3 = 
235800 22 CONTROL CHR 
23801 122 > 
23802 за? К 
238903 13 


The PEEKs in line 40 set A to the value of the first memory address of 
the program storage area. (See the description of the System Variables 
in the next Unit.) Unlike the ZX81 the Spectrum program area moves 
around in memory. 

After printing the numbers, in a revised notation, setting the 
exponent values to have the decimal point after the first digit (a task 


328 


automatically done by the operating system) the program prints the 
first address (23755), which is the first byte of the program area. It then 
prints the value stored in this byte, followed by the character code (if 
it’s not a control character). Codes not corresponding to a character 
with a printed form produce a question mark. 

The first two bytes hold 0 and 10. This is the line number, stored, 
unlike all other two-byte numbers, with the more significant byte first. 
The next two bytes hold the number of characters in the line, stored in 
normal fashion, with the least significant byte first. We then have code 
245, which is the keyword PRINT, the first instruction in the line. This 
is followed by the characters 2 and 3, for printing in the program listing. 
This is followed by code 14, which is a control code indicating that the 
next 5 bytes are to be interpreted as a number. There are then five 
bytes storing the number 23, in the special form in which the Spectrum 
handles integers. We will deal with this in the next Unit. Notice that 
the code 14 defines for the Spectrum the way in which a character or 
number (stored in the same binary form in a memory byte) is to be 
interpreted. 

After the five bytes of the number comes the ENTER character (13), 
signifying the end of the program line. Addresses 23772 and 23773 hold 
the next line number, then comes the number of character bytes in the 
line, and so on. Note that the number 123E8, which was input in this 
form, is stored as this sequence of characters, even though it prints in a 
different form, due to the operating system using the five-byte form to 
decide what number is to be printed. 

Trace the program further than the third line we have included in 
the printout, and ensure you can follow the program line arrangement, 
as we will refer to this in connection with a program to renumber 
program lines automatically later in the text. Although the Spectrum 
and ZX81 character codes are different, the program line arrangement 
is the same. 

Because we know that the address at which a program listing starts 
can be found, and the format of the program listing in memory, we can 
use PEEK to extract data from a program line. This can be useful to 
store data. Enter and run the program below. You should be able to see 
how it works. Remember that the first character after the line number 
(two bytes) and the line length (two bytes) will be the REM statement. 
The characters to be PEEKed will follow this. 5 bytes therefore need to 
be added to the start address of the program area. 

The Spectrum user needs to use the PEEK expression to find the 
start of the program (the address given by M): 


40 REM RIALCNIS 

20 LET M= PEEK 23635+256# PEEK 
22636 

30 PRINT АТ 10310 

40 FOR F=7 TO 0 STEF -1 

S50 PRINT СНЕ% PEEK СМ+5+Р); 

&O NEXT F 


329 





On the ZX81, the start of the program area is fixed. 5 can be added to 
this to give the address of the first byte of memory we are interested in 


(16509 + 5 = 16514). 


10 REM RIALCNIS 

20 PRINT AT 10,10; 

30 FOR F=7 TO @ STEP -1 

40 PRINT CHRS PEEK (16514+F); 
50 NEXT F 


The reverse procedure is also possible, using POKE. Try this 


program. 
ZX81: 
18 REM ABCDEFG 
20 FOR F=0 TO 6 
30 POKE (16514+F) , 29+F 
40 NEXT F 
Spectrum: 


10 REM ABCDEFG 

20 LET М-РЕЕК 23635+256*PEEK 23636 
30 POR F=0 TO 6 

40 POKE (M+5+F) ,48+F 

50 NEXT F 


Тһе Spectrum program again uses а РЕЕК to find the program area 
start address, and the different character codes require different values 
added to F to give the same result. 

Run the program, then LIST it and see what has happened to the 
REM statement. If you want an illustration of the care needed when 
POKEing into programs, try setting F = 0 TO 8 and run the program 
again. LIST it, and then try to edit your listing. The ZX81 may crash, 
and if your screen blanks out or produces other strange effects you will 
have to reset it by pulling out the power supply plug and re-inserting it. 
The Spectrum is more tolerant of this sort of treatment, and will just 
give an error message, but the program listing is corrupt, and NEW 
will have to be used. 

Storing information in a REM statement in this fashion, given that 
as you have seen it can be accessed with PEEK and updated with 
POKE, can provide a useful alternative to storing data in variables. 

The layout of the program listing in memory, starting at a known 
address, enables us to write a program which will renumber the 
program lines. Here’s the program for the ZX81: 


1 REM "RENUM" 
2 REM REPLACE LINE AND STEP 
30 REM VALUES IF START LINE 
45 REM OR STEP VALUE TO BE 
DIFFERENT 
50 REM RUN IN FAST MODE FOR 
121 REM LARGE PROGRAMS 
1001 REM **YOU MUST REMEMBER** 
1002 REM ***GOSUBS AND GOTOS*** 
9000 REM ***RENUMBER*** 
9010 LET RAM=16509 


330 


9020 LET LINE=10 

9030 LET STEP=10 

9040 POKE RAM, INT (LINE/256) 

9050 POKE RAM+1, (LINE-256*PEEK R 
AM) 

9060 LET RAM=RAM+1 

9070 IF PEEK RAM<>118 THEN GOTO 
9060 

9080 LET RAM=RAM+1 

9090 IF 256*PEEK RAM+PEEK (ВАМ+1 
)=9000 THEN GOTO 9120 

9100 LET LINE=LINE+STEP 

9110 GOTO 9040 

9120 LIST 

9130 STOP 


Modifications for the Spectrum are required as follows: Line 9010 
must be edited to read LET R AM = PEEK 23635 + 256* PEEK 23636. 
Line 9070 must be changed to 9070 IF PEEK RAM<>13 THEN 
GOTO 9060. 

Line 9010 sets a variable RAM equal to the start of the program 
area. LINE (the line number to start the new listing) and STEP (the 
increment of the line numbers) are both set at 10, but could take any 
desired values. 9040 and 9050 POKE into the first and second bytes, 
which hold the line number, the value 1@. Into the first byte goes the 
line number divided by 256, the INT function turning this to an 
integer value. If non-integer values are POKEd into an address, they 
are automatically rounded, but to the nearest whole number, which 
does not give us the desired result if the remainder is 0.5 or greater. 
Into the second byte goes the line number less the value in the first 
byte, obtained by PEEKing the byte and multiplying by 256. 

Lines 9060 and 9070 increment the address and check if the address 
contains the NEWLINE (ENTER) character (code 118 on the ZX81, 
code 13 on the Spectrum), repeating until a new line is found, which 
marks the end of a program line. 9080 adds 1 to RAM, giving the start 
address of the next program line. 

Line 9090 checks the value (line number) held in this and the next 
byte, to see if the process has reached the start of the renumber 
program, passing control to 9120 for listing if it has. 9100 increments 
the line number by the step value and control is then passed back to 
line 9040, and the new line number POKEd into the first bytes of the 
next program line. 

Notice that the program checks each byte in turn. Another way to 
find the address of the end of the program line, which prevents the need 
for this, is to use the data about line length stored in the third and 
fourth bytes of the program line. To do this, delete line 9080 and 
replace lines 9060 and 9070 as follows: 


9060 LET LENGTH = PEEK(RAM + 2) + 256*PEEK(RAM + 3) 
9070 LET RAM = RAM + LENGTH + 4 


This finds the line length, and adds this, plus 4 for the bytes holding 
391 


line number and line length, to the current RAM value, giving the 
address of the first byte of the next line. 

Remember, to use a program like this on the ZX81, you should 
LOAD it before you start to program, and use RUN 9000 when you 
have developed your program. You will also need a STOP instruction 
before line 9000 to prevent your program renumbering itself every time 
you run it. The REM statements are not necessary to the program in 
the listing, of course, but do give the program something to renumber 
as a test. Note that GOSUB and GOTO destination line numbers are 
not renumbered, and you must edit the lines affected to suit the new 
numbering. Take a printer listing or note down the relevant lines before 
renumbering! On the Spectrum, a program can be MERGEd with one 
already in memory, and added at any time. See Unit W2 for this 
facility. 

Loading useful programs, Joined into a subroutine or sub-program 
toolkit, is worthwhile if you are developing a large program. This 
might include, for instance, a sorting routine, error message and 
format subroutines. As with the renumber program, which is deleted 
after use, any unwanted routines can be edited out. 

A utility program like this should obviously have line numbers 
9000 + , and the variables used should not be single letter variables, or 
even variables such as A9, which might be needed in the main 
program. 

The program “TOOLS” in the program library illustrates the 
principle, and provides a basis for you to add further useful 
subroutines. It incorporates a block deletion routine (also listed 
separately), which enables easy deletion of any portions of the toolkit 
program not required to be easily edited out. This includes the facility 
to delete itself! 


U3: System Variables 


The system variables area of memory 1s a fixed area holding 125 bytes 
(ZX81) or 181 bytes (Spectrum) of system variables. These occupy 
either one or two bytes, generally, but exceptions include the variable 
PRBUFF on the ZX81 (16444 to 16476), which stores 33 characters in 
a line, ready for the printer (the printer buffer), the MEMBOT 
variable on both machines, which is a subsidiary number store used in 
conjunction with the calculator stack, and KSTATE and STRMS on 
the Spectrum, dealing with the keyboard and Input/Output 
respectively. 

Single byte variables store a number between @ and 255 decimal. A 
two-byte variable holds a number between 0 and 65535. This is 
because the number of bytes available is 2, hence there are 16 bits, 
which can store 65536 values (@ is a value). To calculate a two-byte 
value in decimal, which we must do because this is how values from 
addresses are returned by the computer, we use (value of least 


332 


significant byte) + 256* (value of most significant byte). Except in the 
case of line numbers for program lines, the first byte is the least 
significant byte of any two-byte number. 

The set of system variables we will look at are those variables which 
hold the addresses of the boundaries between areas of memory. Since 
some memory areas move around, the computer must know where 
each area starts. We can also use this information to find out what the 
current state of memory organisation is for use in various ways. Below 
are tables of the ZX81 and Spectrum memory maps with the system 
variables and their addresses. Note that the system variable names are 
Just mnemonics. They are not recognised by the computer. 


ZX81: MEMORY MAP WITH SYSTEM VARIABLES 


Memory Area System Variable Addresses Contents Returned by: 


System 
Variables 


(Fixed) (16384) 










(Fixed) (16599) 
Program 
Listing 
D-FILE 16396/7 PEEK 16396+256*PEEK 16397 
Display 
File VARS 16400/1 PEEK 1649@+256*PEEK 16491 






Marker Byte 





(Single byte containing CHR$ 128) 






E-LINE 16404/5 PEEK 164044256*PEEK 16495 
Work 
Space 

STKBOT 16410/1 PEEK 16419+256*PEEK 16411 
Calculator 
Stack 

STKEND 16412/3 PEEK 16412+256*PEEK 16413 






Spare 
Memory 


Machine 
Stack 


Gosub 
Stack 


The size of various portions of memory occupied on the ZX81 can be 
found by entering (as direct commands) the following: 


(Stack pointer-not accessible with BASIC commands) 






ERR-SP 16386/7 PEEK 16386+256*PEEK 16387 





RAMTOP 16388/9 PEEK 16388+256*PEEK 16389 


Program listing: PRINT PEEK 16396 + 256*PEEK 16397-16509 
Program, variables, display file and system variables: 

PRINT PEEK 16404 + 256* PEEK 16405-16384 
Approximate memory left for program: 

PRINT PEEK 16386 + 256*PEEK 16387 - PEEK 

16412 — 256*PEEK 16413 


333 


This returns only the approximate number of free memory bytes, since 
it does not take into account the size of the machine stack, because we 
cannot access the stack pointer. Actual memory is always less than the 
value returned. 


SPECTRUM: MEMORY MAP WITH SYSTEM VARIABLES 





















Memory Area System Variable Addresses Contents returned by: 
P-RAMT 2373273 PEEK 23732 +256*PEEK 23733 

User Defined 

Graphics 
UDG 23675/6 PEEK 23675 +256*PEEK 23676 
RAMTOP 23730/1 PEEK 23730 +256*PEEK 23731 


STORAGE 


Note that various marker bytes are used to separate areas of memory, 
as indicated. Program length (listing only) is given by (PEEK 
23627 + 256*PEEK 23628) - (PEEK 23635 + 256*PEEK 23636), i.e. 
VARS less PROG. Program and variables memory requirement is 
given by E-LINE less PROG, with the PEEKs required again as given 
above. All memory areas below 23734 are fixed, with their addresses 
being as given in the previous Unit (see the Memory Map diagram). 
Without the microdrive, CHANS will be fixed at address 23734. An 
alternative method of determining free memory left on the Spectrum is 
to use the following, which uses a routine in the ROM memory. The 


Not accessible with BASIC 
Not accessible with BASIC 
STKEND 26353/4 PEEK 26353 +256*PEEK 26354 


STKBOT 26351/2 PEEK 26351 +256*PEEK 26352 


WORKSP 23649/59 PEEK 23649 +256*PEEK 23659 


E-LINE 23641/2 PEEK 23641 +256*PEEK 23642 


VARS 23627/8 PEEK 23627 +256*PEEK 23628 


PROG 23635/6 PEEK 23635 +256*PEEK 23636 


CHANS 23631/2 PEEK 23631 +256*PEEK 23632 


Fixed (23734) 


334 


number of bytes of free memory 1.е. the size of the spare memory 
section, is given by PRINT 65536 - USR 7962. 


We can use the system variable VARS to determine how numbers 
are stored in the computer. Each different type of variable needs to be 
identifiable as the correct type, 1.е. as a loop control variable, as a 
string variable, etc. This is done by altering the first three bits in the 
appropriate letter codes. (Bits in a byte are actually numbered right to 
left, starting from 0. In the eight bit byte 00100000 , for instance, bit 5 
is set as 1. Bits 5, 6 and 7 in the byte are the ones referred to above.) 

On the Spectrum, all letters in variable names are taken as lower 
case. These letters all have bit patterns starting 011. . . , codes being 
97 to 122. The ZX81 letter codes all start with bits 001 . . . , codes 38 
to 63. Check the binary equivalents of the letter codes to confirm this. 
Since these three bits are always the same, the computer can alter them 
as a signal to indicate which type of variable is being called by a 
particular variable name, which may be the same as the name of some 
other type of variable (e.g. A as a simple variable, A(5) as an array 
variable, A$ as a string variable). The patterns of bytes used are as 
follows: 


Single character variable did... 
Multiple character variable 101... 
Loop control variable Lion 
String variable BID. ..... 
Numeric array variable 100..... 
String array variable (BI PS 


Because the codes for the letters have different values on the ZX81 and 
Spectrum, the effect on the value stored in the byte is different. After 
we've discussed exploring the ways variables are stored, the form for 
each type of variable is given, with the change in the letter code noted 
for both the ZX81 and Spectrum. 

The next program inputs a value for the numeric variable A. This 
will be entered into the VARS area as the first variable stored. Line 30 
PEEKs the value of the VARS system variable, and adds the value of 
the loop variable F, then PEEKs this address. The first value returned 
by the expression in brackets (F = 0) is the address of the first byte of 
the variables store. For a numeric variable on the ZX81, this holds the 
name of the variable, stored as its Code + 64, if the variable name is a 
single character. On the Spectrum it 1s stored as the code of the /ower 
case letter, unchanged. Key in the program and input various numbers. 

10 INPUT A 

20 PRINT "A-";A 

30 FOR F= 0 TO 5 

49 PRINT PEEK (PEEK 16400--256%Р 
EEK 16401 +F) 


50 NEXT F 
68 GOTO 10 


235 


Spectrum users: change the PEEK expression to: 
40 PRINT PEEK (PEEK 23627 + 256*PEEK 23628 + F) 


Input 1.5. The display will be like this: 


ZX81 Spectrum 

А-1.5 А-1.5 

102 (= Code А + 64) 122 ( = Code of lower case a) 
129 (5 byte number follows) 129 (5 byte number follows) 
64 64 

0 0 

0 0 

0 0 


Change the variable name in line 10 to confirm the code. The first byte 
of the 5-byte number is the exponent byte, the following four are the 
mantissa, the number the exponent acts on to get the numeric value. 
The Spectrum has a special form of this for integers. (See below for 
more on numbers.) 

Change the variable name to, for example, AB5, or other variable 
names with more than a single letter in the name, and run the program 
again. You can then confirm that numeric variables are stored in these 
forms: 


Single Character Variable 


1 byte 5 byte number 


Code Exponent Four Mantissa bytes 
+64 7Х81 byte (S = Spectrum) 
+9 s 


Multiple Character Name Variable 

1 byte 1 byte (for each character) 1 byte byte numbe 

Code Code Exponent Four Mantissa bytes 
+128 2Х81 

+64 5 


First character and last character only are stored as code plus values 
indicated. Other characters are stored as the standard character codes. 

The other forms of variable are stored in the byte sequences shown 
below. Write programs to confirm these memory arrangements. You 
will need a loop that prints the correct number of bytes. The FOR- 
NEXT sequence, for example, which takes 18 bytes, can be simply 
programmed by deleting lines 10, 20 and 60 in the program above, and 
changing the loop to @ TO 17. 








336 


Loop Control Variable 


5 b e numbe ° 2 
Code Start value Limit value Step value Line number 
+192 Zx81 for next jump 


+128 S 






The control character is stored as code + 192 on the ZX81, + 128 оп 
the Spectrum. The value is incremented or decremented by the step 
value each time the NEXT instruction is executed, and the value 
checked against the limit value after each such change. The line 
number (stored as more significant byte first, as are the program line 
numbers) is the line number of the FOR...TO instruction plus 1, as 
this is the destination line for the NEXT instruction to jump to. 


String Variable 


The single letter name is stored as the code less 32 on both the ZX81 
and Spectrum. The number of characters is what is read by the LEN 
instruction. For a null string, this is zero, and no character bytes are 
stored. 


Numeric Array Variable 









1 byte 2 bytes 1 byte 2 bytes 2 bytes 5 bytes each eleme 
Code Number of bytes umber of Size of Size last 

+96 2Х81 following dimensions first dim. dim. 

+32 S 





Notice that an array such as A(7) is a single dimensioned array. (It will 
require 1+2+1+2+(7*5)=41 bytes.) The bytes storing the size of 
each dimension enable the computer to keep track of a multi- 
dimensioned array stored in a linear sequence. For example, DIM 
A(3,3) sets a sequence of the eight data bytes, plus 9*5 bytes to hold: 


t — Te —P 1.3 
ae 2,1 — 2,2 — À 2.9 
Cop 21e 22 eni 


Work out how a 3-D array, say A(2,3,4) will be stored. 


337 


String Array Variable 


1 byte 1 byte 2 bytes 


No. of |Size of first 
dims. dim 


2 bytes 















Ho. of bytes 
following 





2 bvtes 1 byte per chy. 
Length of Code 
strings 


You should now see why string arrays must have fixed length strings, 
since otherwise the computer could not use the length of string datum 
to step through the linear sequence to find the appropriate set of 
character codes making up an element in the array. 

The next manipulation we will look at concerns the way the ROM 
memory holds the characters to be printed on the screen. 

Starting at address 7680 on the ZX81, and at 15616 on the 
Spectrum, each character is held in a sequence of 8 bytes of memory. 
The binary number of each byte represents, in this case, a sequence of 
075 and 175, which hold the pattern of the character, corresponding to 
the 8 x 8 grid of points in each character cell on the screen which is used 
to print a character. 

If we take the letter A, for example, it 1s represented like this: 


DECIMAL BINARY 
NUMBER NUMBER 

0 00000009 

60 00111100 

66 01000010 

66 01000010 

126 01111110 

66 01000010 

66 01000010 

0 00000000 


А zero is read as an instruction to leave blank the corresponding point 
on the screen, and a 1 indicates it is to be blacked in. 

The following program will illustrate the principles. It takes one of 
the 8-byte sequences of numbers stored in ROM and gives the decimal 
and binary forms of these numbers. The pattern of ones can be seen. 
Remember Decimal 0-255, Binary 00000000 to 11111111, is held in 
each byte. The relevant portion of memory is accessed by using the 
code of the character concerned. Starting at address 7680 on the ZX81, 
the first of the addresses for any character is given by 7680 + CODE 
(Character)*8. The eight addresses are then PEEKed one by one, and 
the decimal number given then the binary form printed out. Lines 110 
and 130 convert the decimal to binary and print it. 

Whilst the Spectrum characters are held at a specific address in 
ROM, the system variable CHARS, which is at addresses 23606 and 
23607, holds the start address of the character memory sequence, and 


338 


can be POKEd with different values to start the sequence elsewhere in 
memory. This can be used to define a new start point for the character 
set in RAM, and define a whole new character set on the Spectrum, in 
addition to the facility for user-defined graphics (which will be dealt 
with in Unit W2). CHARS returns a value which is the start address of 
the characters, less 256. The character set that is stored in ROM starts 
with the Space symbol (code 32) and runs in sequence to © (code 127). 
To access the right sequence in ROM, we must use the start value 
given by CHARS, which is 15360, plus the character code multiplied 
by 8, just as on the ZX81. The fact that CHARS points to 256 bytes 
below the start of the printable character set adjusts for the fact that the 
first character that can be accessed has code 32 (since 32*8 = 256). 
For the program below, therefore, Spectrum users need to put LET 
A = 15630 in line 10, which is the normal value given by PEEKing the 
CHARS system variable, and the right address in ROM is accessed. 


10 LET A=7680 

20 PRINT “INPUT A CHARACTER" 
30 INPUT А5 

40 CLS 

50 LET C=CODE А5 

60 LET D=8*C+A 

70 FOR X=0 ТО 7 

80 LET L=PEEK (D+X) 

90 PRINT D+X;TAB 6;L 

100 FOR Z=18 TO 11 STEP -1 
110 PRINT АТ X, Z;L-2*INT (L/2) 
130 LET L=INT (L/2) 
140 NEXT Z 

150 NEXT X 


If we add: 


120 IFL-2*INT (L/2)- 1 THEN PRINT 
AT X,Z +10; “Ш” 


we can print out a large version of the character. The routine will only 
work for the standard characters and graphics (codes 1 — 63 on the 
7Х81). Inverse characters and functions on the ZX81 are not held in 
this form. All Spectrum characters up to code 127 can be accessed. 

We can use this principle to produce any size character we want, 
within the limits of the screen. 

The next program allows a string of up to 4 characters to be printed 
out. You should be able to follow the same steps in this program as in 
the previous one - the method is essentially the same, working on a 
string of characters, rather than a single character, and only using the 
print routine. To fit 3 lines of 4 characters (which would take 24 lines) 
we neglect the first (top) byte, since this is blank for all the letters and 
numbers. This lets us fit 3 lines in, but graphics characters will look 
strange, since they do use the top line. A different method is used to 
read out the binary values for printing. To avoid complex 
manipulations of PRINT AT values, which would be required if we 


339 


used the system in the previous program, each line of the ROM is 
checked for each character in turn across the line, which enables a 
continuous PRINT operation. 

Each binary value is checked in turn to see if it is Ø or a 1 by doubling 
the value of X (line 180), so that it is either >128 (1) or <127 (0). Line 
150 takes 128 away if a 1 is found. If you do not understand this 
process, take any binary number and trace the operation through lines 


120 to 190. 


© REM "BIGFREINT" 
& REM xALLüWS = LINES OF 4 
#CHARACTERS EY OMIT- 
*TING TOF LINE CELANE 
*FOR LETTERS AND 
xNLUMEERZ» OF xz GRID 
10 DIM Ac43 
20 PRINT "INPUT STRING (МАХ 12 
LETTERS / МОМЕЕЕ >" 
25 INFUT АФ 
30 ELS 
35 FEM *FOR EACH LINE* 
40 FoR Fzi TO 3 
= REM xGET CODE INTO ARRAY * 
xFOR EACH LETTER % 
SO FOR ісі TO 4 
во LET ACLI= CODE АСЕ? 
70 NEXT L 
75 REM xUFDATE At 
So LET А%=А%(5 TO 3 
ез REM «BYTES 1 TO 7 OF * 


* ж ж ж ж 


#ITHARACTER IN ROM + 
ЭО FOR B=1 TO 7 
95 REM *FOR EACH LETTER OF % 


*LINE * 
100 FOR C=1 ТО 4 
105 REM *GET BYTE VALLE 
110 LET X= PEEK (7@80+A(C) #8+B) 
115 REM #FOR EACH BIT* 
1209 FOR V-O Tü 7 
125 КЕМ *IF ZERO THEN JUMP 
190 IF Х«128 THEN GOTO 170 
140 PRINT "Ш"; 
145 REM #DECREMENT CHECK * 
жУЙІМЕ + 
150 LET Х-Х-128 
160 GOTO 180 


170 PRINT " "i 

120 LET Х-Хжу 

ісе REM xNEXT BIT* 

190 NEXT V 

19% FEM %МЕХТ LETTER OF LINE* 
200 NEXT C 

205 REM xNEXT BYTE OF RüOM* 
210 NEXT Ë 

215 REM *NEXT GERDOLF OF 4+ 
220 NEXT F 

220 REM #*ЕМП++ 


340 


Spectrum users must insert 15360 in place of 7680 in line 120. 

The program, ‘‘HEADLINER”’ in the program library, uses the 
character array in ROM to print banner headlines on the printer. If 
you inspect this program, you will see that it has a method of enabling 
the inverse characters of the ZX81 to be printed by changing them into 
normal characters (using CHR$(CODE А%-128)) to access the 
pattern in memory, then reversing it again when it comes to print it. 

RAMTOP may be set to a lower value to give memory space outside 
that usually used by the operating system. This has an application 
which is occasionally useful on the ZX81, regarding the use of CLS 
after SCROLL has been utilised. This does not apply on the Spectrum. 
Clearing the screen can take a long time after scrolling. Try this to 
illustrate: 


10 FOR F=1 TO 30 


20 SCROLL 

30 PRINT "XXXXXXXXXXXXXX' 
40 NEXTF 

50 CLS 


This is due to the fact that SCROLL interferes with the way the display 
file is set up on a ZX81, with more than 3.25k of RAM available — with 
a full screen of spaces where no characters exist. A PRINT line after 
SCROLL is just the required length, with nothing filling up the line if 
there are no characters. To clear the screen, the ZX81 counts up 24 
new lines, then inserts spaces to recreate a full display file. If less than 
3.25k are available, an empty screen is just 24 newline characters. 
RAMTOP is set with 0 in address 16388 and 128 in 16389 оп switch- 
on (0 + 256* 128 = 32768, the address of the first non-existent byte). 


POK Eing values to set RAMTOP below 19634 (16509 + 3.25k) will 
set up the minimal display file and CLS will act instantly. Your 
program must be less than 3.25k (say 3k as returned by the commands 
given above). The convenient value to use is 76 poked into 16389. This 
sets RAMTOP as 0 (value of 16388 unchanged) + 256*76 = 19456, 
which is rather more convenient than POKE 16388,76 followed by 
POKE 16389,177 (177 + 256*76 = 19633). Insert 45 POKE 16389,76 
into the program above and run it again. Note that if you NEW the 
program and then key in PRINT PEEK 16389, you will still get 76. 
RAMTOP must be re-set by POKEing the correct value (128) or by 
switching off and on again to re-set. 

On the Spectrum, RAMTOP is moved using CLEAR. The 
instruction CLEAR (N) resets RAMTOP to the address given by N. 
RAMTOP is reset to this value, and remains at this address until reset 
by CLEAR (or switching off and on again.) It is not reset by NEW. 

The procedure given below for storing data above RAMTOP is less 
useful than it is on the ZX81, because the Spectrum can MERGE a 
program with another LOADed in from tape (see Unit W2). This 


341 


program can be mostly data (although it must have program lines). 
However, this method will work on the Spectrum, and shows the 
technique of moving Information around in memory. If you progress to 
machine-code programming, this is one way in which you can store 
machine code. 

RAMTOP may be moved so as to reserve space at the top of 
memory. On the ZX81, this area will not be affected by NEW or 
CLEAR, or the automatic NEW that occurs with LOAD. It can be 
used to store data for use by another program, after the data have been 
defined by a previous program. This procedure, available with less 


complications on some computers, is performed as follows on the 
ZXO1. 


i) New values are POKEd into the RAM TOP system variable, so 
that the system considers the top of RAM to be lower than 
address 32767. This reserves space above the new RAMTOP 
value. NEW is then used. POKEing RAMTOP has no effect 
until NEW has been used. How much space is reserved depends 
on the number of bytes of data we require to store. (Spectrum: 
See above for resetting RAM TOP.) 

п) The program to use the data must have been written and stored 
on cassette. This has instructions to copy into the variables area 
the data stored. It must initzalise the same variables or arrays for data in 
the same sequence as the program which provides the data. 

ii) The program to store the data intialises the arrays or variables 
for the data first, before any other variables. The program is then 
run. The required number of bytes are taken from the start of 
the variables area (found using VARS), and copied to the area 
above RAMTOP (found using RAMTOP). 

iv) Program 2 is then loaded. It initialises the variables as did 
program 1, finds VARS and RAMTOP, and reverses the 
procedure, PEEKing RAMTOP and POKEing the values 
found into the variables area. It can then proceed to use the 
data. 


The amount of memory needed for storage is calculated from the 
information given above about the method of storage of variables. As 
an example, let us assume we want to store an array D(20) for use by 
another program. We will use this as a short example program. In 
practice, the technique will require a second program to use the data to 
have been written and SAVEd, but the examples are short enough to 
key in. 

Reference to the information about variables shows us that an array 
D(20) requires 106 bytes. On a ZX81, we must set RAMTOP as 
32768 — 106 = 32662. This is the address of the first non-existent byte, 
and will be the address of our first storage byte. To set RAM TOP to 
this value, we POKE 16389,INT(32662/256) as a command, followed 


342 


by POKE 16388,32662 – 256*INT(32662/256). Of course you could 
use the computer to work these out beforehand, and POKE the values 
directly. NEW the computer, then enter this program and run it. On 
the Spectrum, RAMTOP is set with CLEAR, and can be done simply 
by using: 


CLEAR (PEEK 23730 + 256* 23731 – 106) 


5 REM "DSTORE" 
10 REM **DATA ABOVE RAMTOP** 
20 DIM D(249) 
30 FOR F-1 TO 26 
40 LET D(F) =F*F 
50 NEXT F 
60 LET VARS=PEEK 164004256*PEE 
K 16461 
70 LET RAMTOP-PEEK 16388+256*P 
EEK 16389 
80 FOR Е=0 TO 105 
90 POKE (RAMTOP+F) ,РЕЕК (VARS+F) 
100 NEXT F 


The first active line (20) dimensions the storage array. The loop of lines 
30 to 50 merely insert some values into the array. Lines 60 and 70 find 
the values of VARS and RAMTOP. The loop of lines 80 to 100 stores 
each byte of the variables store that contains array D above 
RAMTOP. Spectrum users must insert the correct PEEKs in lines 60 
and 70 to get the values of the VARS and RAMTOP system variables. 
The same must be done with the data retrieval program below. 

Now use NEW, and enter the program to retrieve the data. This 
reverses the procedure. After initialising D(20), and finding VARS 
and RAMTOP, it POKEs the value of each byte stored above 
RAMTOP into the bytes of the variables area containing the array. 
Lines 70 to 80 print out the array values. 

1 REM "DFEICH" 

5 REM **RETRIEVE STORED DATA 

**FROM MEMORY  ****** 

10 DIM D(29) 

20 LET VARS-PEEK 16400+256*PEE 
K 16401 

30 LET RAMTOP-PEEK 16388+256*P 
EEK 16389 

40 FOR Е-й TO 105 

50 POKE (VARS+F) ,PEEK (RAMTOP+F) 

60 NEXT F 

70 FOR F=1 TO 20 


80 PRINT D(F) 
90 NEXT F 


On the ZX81 only, you can use CLEAR: the array will be wiped from 
memory, but remains safe above RAMTOP. Running the program 
again will retrieve the data once more. This is obviously a technique 
useful not only for passing data between programs, but also for 
allowing CLEAR to be used and still having current data (i.e. that not 


343 


assigned by LET statements) preserved. This does not apply to the 
Spectrum, since CLEAR re-sets RAM TOP. 

The complete list of system variables for both the ZX81 and the 
Spectrum is given in Appendix V. The timing variable FRAMES is 
used in the “КЕАСТ”” program analysed in Unit V3. 


MORE ON NUMBERS AND COMPUTERS 


The way in which numbers are manipulated by the operating system in 
a computer does not concern us here, but the way numbers are held, 
and their form, are important in computing, even if the precise manner 
in which calculations are carried out is a separate topic. We will deal 
here with enough detail of the binary system to enable 5-byte floating 
point to be understood. 

We briefly introduced the binary system earlier. To explain further 
the use of a system using powers of 2, and how any number can be 
represented % a certain level of accuracy, key in this program: 

10 REM "POWERS OF TWO" 


28 PRINT "POWERS OF Two" 
30 PRINT "------------- " 


40 PRINT "2**N";TAB 10; "М№";ТАВ 
16;"2** -N" 
50 PRINT 


60 PRINT TAB 6;"1 0 1.9" 

70 FOR F-1 TO 16 

80 PRINT TAB ( 17-LEN STRS (2**F 
));2**F;TAB 10;F;TAB (14+(F 
>3));2%%-Е 

90 МЕХТ Е 


(Replace ** Бу # for the Spectrum at each occurrence in the program). 
You will get a display like this: 


POWERS OF TUO 


mx xM ч eee -M 
1 & 23. 
c і e. 
41. е е.гБ 
б a G. 1 
15 4 . 0825 
32 5 a 93125 
64 ы «"ӘӨзбесе 
128 а „ гат >= 
256 а |. yl == 
S123 э -дәлзезіге 
1924 18 -@B@2907SES5625 
2048 із „ 5345525583065 
4995 12 PAAS L 14065535 
6192 13 |. їз YT = 71 
163524 із „ асас 22351355 
32768 15 „ зз ЗЫ Г БН 
65536 isc «"Әсоелкгезуаә 


Notice that we have positive powers of two оп the right, giving integer 
values, and negative powers, giving fractions which are represented as 
‘decimal decimals’. The emphasis in the comment above about 
accuracy stems from the fact that there are limits to the accuracy 
obtainable with every number system. The fraction 1/3 is never 


344 


accurately represented in the decimal system, however many decimal 
places are used. The same goes for many numbers in both decimal and 
binary notation. If you study the display it should be apparent that 
with the binary system, only numbers equal to certain decimal values 
are accurately represented. Decimal .6875, equal to 1/2 + 1/8 + 1/16 is 
accurately represented by binary .1011, for example, but with a single 
byte (8 bits), any number varying by .001953125 (2-7) above or below 
the value represented in the byte will appear the same to a computer 
reading this byte. 

To increase the accuracy of representation of numbers, a larger 
number of bytes is needed. This also allows larger numbers to be dealt 
with. The ZX81 and Spectrum use ‘‘5-byte floating point’’ 
representation of numbers. The ‘FLOAT’ program gives the decimal 
value held in each byte of the five by PEEKing the variables area: 


1 REM *FLOAT* 

2 REM FRINTS FLOATING FOINT 

FORM OF A NUMBER 

10 PRINT "ENTER A NUMBER" 

20 INPUT N 

ЗО PRINT "THE NUMBER "FN" IS 
HELD» "IN THE 7Х681 А5:-" 

40 FOR F=1 TO Š 

45 REM FEEKS START OF VARIABLE 
STORE (VARS) AREA IN MEMORY 

SO PRINT FEEK С PEEK 16400+2546 
ж PEEK 16401-4F);" "3 

60 NEXT F 


On the Spectrum you should change Line 50 to read PRINT PEEK 
(PEEK 23684 + 256*PEEK 23685 + F). Input only non-znteger values 
(we'll explain why this is the case a little later). 

If you input 2.4, you will get a screen display of: 


130 29 153 153 154 


Try other numbers. There is no obvious pattern to the decimal values, 
other than the first number not varying much from around 128 unless 
you input very large or small numbers. This is the exponent byte (as with 
the E notation). The next program, “ЕТУЕВҮТЕ”, displays the 
mantissa number (the other four bytes) in decimal and binary form, 
and the exponent byte in decimal form: 


10 REM "FIVEBYTE" 

ZO PRINT “INPUT NUMBER" 

ЗО INPUT N 

40 PRINT “NUMBER="7N 

50 LET EXP= PEEK (1+ PEEK 1640 
O+256% PEEK 16401) 

60 PRINT “EXPONENT="; EXP 

70 LET Р=ЕХР- 128 

80. IF P <> -128 THEN PRINT “2 
жж Hers Mats ++ Р 

90 IF EXP=0 THEN PRINT “USED F 
OR ZERO ONLY" 


345 


100 PRINT "MANTISSA BYTES: -" 
110 FOR F=2 TO S 

120 PRINT TAB (F-2)#5; PEEK (F+ 
PEEK 182400-256% РЕЕК 16401); 
130 NEXT F 

140 ЕСЕ Е=2 TO S 

150 LET D= PEEK ¿(F+ PEEK 16400+ 
256% PEEK 16401) 

160 LET Es$z"" 

170 LET L= INT (0/2) 

120 REM LET АФ=("1" AND П-72 + 
C"O" AND П-2ж-0) 

181 LET A$- ZTR$ (D-Z*L>) 

190 LET BS=A$+E% 

200 LET IL 

210 IF 050 THEN GOTO 170 

220 IF LEN E$Z8 THEN LET E$z"oo 


o00000"c1 TO (8- LEN E$))+EËE%$ 
230 FRINT TAE (F-20*8; E$ 
240 NEXT F 


(Once again, on the Spectrum change ** to Î at every appearance. 
Line 50 needs to be changed to read LET EXP = PEEK (1+ PEEK 
23684 + 256* PEEK 23685) to give the start of the Spectrum variables 
area. Change 16400 to 23684 and 16401 to 23685 in lines 120 and 150 
also.) 

A number stored in 5-byte floating point notation has an exponent 
byte, which acts, as with the decimal E notation, to shift the binary 
point along to the correct place. 

The exponent value is stored as exponent plus 128, and can hence be 
negative or positive. It works in powers of two, and the value of this 
(exponent raised to the power of two) is given in the program. The 
representation of zero has a special form, such that the exponent is 0, 
and the values of all the other bytes is also zero. The value stored in the 
exponent byte is thus between 1 and 255, giving possible exponent 
values between - 127 and +127. The range of numbers covered 15 
then what would be presented if our POWERS ОЕ TWO” program 
went on to 127 rather than just 16. 

The mantissa value (represented in the next four bytes) is converted 
to the numeric value by multiplying it by 2 raised to the power of the 
exponent: N - M*2*, where M is the mantissa value and e is the 
exponent (value stored in exponent byte less 128). This process can 
also be considered as moving the binary point the number of bits given 
by the exponent. 

The mantissa bytes are considered as a single sequence of binary 
digits, with the binary point at the beginning. The program gives the 
values stored in each byte (as with the “ЕГОАТ”” program), and then 
converts to binary to give the mantissa sequence. Since the first bit of 
the mantissa sequence is always 1 (the mantissa 1s always between .5 
decimal and 1 decimal, but never reaches 1, i.e. 0.5< = m<1) the first 
bit 15 used as a зол bit. If the number is positive, the first bit is changed 
to Ø. If it is negative, the first bit is set to 1. This is used as a means of 
handling negative numbers, since all the numbers generated in the 


346 


floating point notation are positive, and an equivalent to the ‘ — ' sign is 
needed to show negation. 

Input 0.75 into the computer when prompted. The display will be 
like this: 


INPUT NUMBER 
NUMBER - 0.75 
EXPONENT - 128 


2**0-1 ( 4 on Spectrum) 
MANTISSA BYTES: 
64 0 0 0 
01000000 
00000000 
00000000 
00000000 


The evaluation is as follows. The first bit is a zero in the mantissa. This 
indicates a positive number. The first bit is changed to a 1, and the 
value of the mantissa is now .11000...0. The trailing zeros are ignored. 
Binary .11 is decimal 0.75 . The exponent value is 0, and 2 raised to 
the power 0 is 1. So we have a value of 0.75*1 = 0.75. If you input 
— 0.75, the display is identical except for the first mantissa byte ( + 128) 
because of the first bit now being 1, and the first mantissa bit, changed 
to 1 to indicate a negative number. This is left as 1, and evaluation 
then proceeds as before. 

Now input 3.75. The exponent is 130, 2**2 ( Жоп Spectrum) is 4, 
and the mantissa bits hold the sequence 01110... The first bit changes 
to 1, and this gives .1111 binary, 0.9375 decimal. 4*0.9375 = 3.75 . 
The alternative way of viewing the process is to consider the exponent 
as moving the binary point along. In this example, we have the 
sequence .1111, and since the exponent value is 2, the binary point 
moves the same number of places to the right, to give 11.11 , which is 
3.75 in decimal. In the previous case, with 0.75, the exponent value 
was 0, so the point was not moved, and the bits were .11 . Negative 
exponents move the binary point to the left, adding zeros. 

The Spectrum has a special representation for integers in the range 
+ 65535 to — 65535, in which the first byte (exponent byte) is zero, as 
is the fifth byte. The second byte acts as a sign byte, holding 0 if the 
number is positive, and 255 if the number is negative. The third and 
fourth byte hold the number (least significant byte first). You can use 
the **FIVEBYTE'' program to investigate this representation if you 
are using a Spectrum. 

To illustrate rounding errors and an otherwise puzzling aspect of the 
representation of numbers, input 1/2 into the ‘‘FIVEBYTE”’ 
program. We get exponent byte = 128, exponent 128 ~ 128 = 0, and a 
zero in the first bit. This changes to a 1, and we have .100.... Exponent 
Is zero, so we don't move the binary point and get .100...., which is 


347 


0.5, and equal to a half. Thus far all is well. If we like, we can consider 
that we got .100.... and multiplied it by zero to get our half. As we said 
above, the two processes are identical. But now input 0.5. This should 
be the same, but instead we get exponent equalling 127, and 0111....1 
(thirty-one 1’s)! We seem to have an error. However it is a pretty small 
one, though it explains why the computer rounds its numbers. To 
avoid considering % as not equal to 0.5 it has to take into account the 
fact that the decimal to binary conversions have these inaccuracies. 
Binary addition of two 1’s causes a @ to be placed in that byte, and a 1 
is placed in the next column to the left. (If you’re interested, the other 
rules for addition are: 1 and 0 give 1, 0 and 0 give 0, three ones (1, 1 
and a carried 1) give 1, carry 1 to next column on the left. Try a few 
simple sums!) This means that if a 1 is added to the least significant bit 
of our sequence of ones: 


пека жа 1111 
1 
0 
I. (carry) 
0 
1 (carry) 
0 
1 (саггу) 
etc 


all the 1's will become zeros, and the last carry would put 1 in the first 
bit, which would make it the same representation as the % sequence, 
but this also has a 1 in it. This forces a carry to a non-existent bit to the 
left of the mantissa. This gives us 1.0 as our binary, and the exponent 
shifts this (exponent = - 1) to .100...., which is correct. Or we сап 
consider this as 1.0 binary (1 decimal) multiplied by 2 ` '(0.5). So the 
error is in the least significant bit. The size of the error is thus 2~*’, the 
value of the right-hand 1. This is fairly small! The computer rounds 
numbers to ensure these inaccuracies do not cause errors. It considers 
numbers equal if the difference between them is less than a certain 
amount. Rounding errors can still build up under some circumstances, 
however, and it is important to note that no computer performs totally 
accurate arithmetic, except with integer values. 

You may be a little overwhelmed by numbers at this point, but 
before we give them a rest we should introduce you to another 
numbering system — Hexadecimal. 

This is another numbering system much used in computing, 
although it has no practical application for us at present since the 


348 


Hexadecimal system (often abbreviated to Hex) is primarily used in 
machine-code programming which is beyond the scope of this text. 
Whereas binary is base 2, and decimal base 10, hexadecimal is base 16. 
This is a convenient system for computers using 8-bit words, since 
16 x 16 = 256. Any value which is held in a single byte can thus be 
represented by a two-digit hexadecimal code. The system uses the 
digits 0 to 9, and goes on with A, В, C, D, E and F, to represent the 
numbers 1 to 16. Here is how the system counts: 


Decimal Hexadecimal 

Ø 0 (9 x 164) 

1 1 (1 ж 16°) 

9 9 (9 x 16^) 

10 A (10 x 164) 

11 B CUL 167) 

15 F (15 x 167) ó 
16 10 ( 1 16.) +, ( Ø x 164) 
17 11 Ci x15)4CI1x]l15 ) 
25 19 (Tx 161) + C Ox 165) 
26 1A lx 167) + (20 x 167) 
31 lF (XX x 161) + #18 ш 160) 
32 20 (o2 167). + í Өле 16”) 
154 9A ( 9 x 161) + (10 x 164) 
155 9B ( 9 x 167) + (11 = 18") 
159 OF (ox 161) + (15 x 164) 
16¢ AG (16 x 16) + (Ø x 16’) 
250 FA (18% 16°) 4°16 x 167; 
254 FE (15 x 161) + (14 x 165) 
245 FF СІЗ «x 16°) = CS ж 167) 


As with any number system, we could go on (256 is 100 hex, etc.), but 
the use of hexadecimal is in representing binary numbers in a more 
convenient form than strings of 1’s and 075, which are difficult to read 
and easy to make mistakes with (unless you аге a computer’). 

The advantage of hexadecimal notation is that any 8-bit binary 
number is convertible to hex far more easily than into decimal, due to 
the relationship of base 2 and base 16 numbers. Base 16 is base 2*, and 


349 


this means the 8 bits of a byte can be divided into two sets of four bits 
(remember 1111 binary = 15 decimal = Е hex) and converted to the 
corresponding two hex digits. For example, the number 116 decimal is 
in binary 01110100. Split into two groups of four bits, 0111 and 0100, 


we convert each group to a hex digit. 


0111 binary (7 decimal) is 7 hex 
0100 binary (4 decimal) is 4 hex 


The number in hex is 74. Check this: (7 x 16) + (4x 16°) = 112+4= 116. 
Again, 93 decimal is 01011101 binary: 


0101 binary (5 decimal) is 5 hex 
1101 binary (13 decimal) is D hex 


The number in hex is 5D. (5 x 16) + (13 x 16°) = 80 + 13 = 93 

To avoid possible confusion when both hexadecimal and binary 
numbers are being used, a small h should be used after a hexadecimal 
number. Our examples above would be 74h and 5Dh. Hex numbers 
are grouped in twos, and the leading zero should be used for numbers 
less than 16 decimal, so that 12 decimal should be written 0Ch, and not 
C or Ch. 

Similarly, numbers up to 65535 decimal (held in two bytes of 
binary), are representable with four hex digits. 11111111111111111 
binary is thus FFFF hex, 10101101001101110 is 1010 (A)/1101 
(0)/0011 (3)/1110 (E): AD3Eh. Work out the value of this in decimal. 

The program library has programs which convert decimal to hex and 
vice versa (“НЕХПЕС” and ‘‘DECHEX’’). Analyse these programs 
to see how they work. The CODE and CHR$ functions are used to 
check the hex notation, or produce it. 


Exercises 


1 Alter the “СНКОМ” program to print just the large character, 
and then the inverse form next to it, by reversing the printing 
instructions for the character to be printed when a 0 or 1 is found 
in the binary form. 

2 Using the “BIGPRINT” program as a basis, store the charac- 
ters of each line of the large characters in an array, so that a 
scroll routine can be used to cause the message to disappear off 
the top of the screen line by line, and re-appear at the bottom. 

3 Write programs to store a string array above КАМТОР, and 
then retrieve it. Use a three-dimensional array. 


350 


PART FOUR 


APPLICATIONS PROGRAMS AND 
GAMES 


ш 


3 ЖЕШСИН, 





Өре FIFAHSOOBS РИТА ЗА 
23127. 





SECTION V: APPLICATIONS PROGRAMS 


V1: Programming for Applications 


You have been introduced to the full set of ZX81 BASIC instructions. 
Spectrum users have some additional instructions in the Spectrum 
superset of BASIC, but we have attempted to show how all necessary 
operations can be performed on the ZX81 and the Spectrum merely 
makes some operations easier to implement. We have covered a range 
of operations, involving loops, lists, array manipulation, sorting, 
subroutines etc., and the implementation of control structures. These 
are the raw material of programming. The combination of what you 
have learned about algorithms, design, program structures, 
manipulations and methods with the task you wish the computer to 
perform produces an applications program. 

There are no rules to derive algorithms. If there were, they could be 
coded into a master program that would write our programs for us! We 
have illustrated ways of thinking about a problem that can help, but 
each program we wish to write presents a unique problem. Familiarity 
with the language and control structures, and with existing solutions to 
a variety of problems, either other people’s or your own, make it easier 
to program. As with most things, the art and craft of programming 
becomes easier with practice. The importance of keeping notes about 
programs you have written, and on solutions to problems you have 
found in analysing other programs, is that it will prevent you re- 
inventing the wheel. As you write more programs for yourself, you will 
find that you come to recognise the method (or methods - there is 
seldom only one way to perform a given task!) by which you can 
implement and code each module of your program. 

Modular, structured program design methods help to break down a 
programming problem to these recognisable chunks, and you wil 
recognise more aspects of a problem as having been met (and solved!) 
before as you gain experience. 

You will also become familiar with the types of data structure 
required in a program to make it possible to manipulate the data 
efficiently, and grasp more quickly and clearly that, for example, a 
given set of data is more efficiently (i.e. easily) handled in a multi- 
dimensional array than in separate lists, or that a similar routine in 
different program modules could be handled by a single subroutine if 
suitable variables were initialised before calling the subroutine. 

Experience cannot be transferred, and there is no substitute for 
practice, but examples can be given. After the important topic of 
writing user-friendly programs has been dealt with in the next Unit, we 
give examples of programs written to perform specific tasks, to 
illustrate the process of designing applications programs. Games 
programming is briefly dealt with in the following Units, since games 


393 


are a good testing ground for problem-solving and programming 
techniques. 


V2: Instructions and Input Checks 


If you have written your own program, you know which inputs the 
program requires, in what form and when. You know, for example, 
that when ‘‘ANOTHER СО?” appears on the screen, you must press 
the Y key to run the program again. 

Now consider what happens if someone else wishes to use the 
program (or if you return to it after some weeks). There is not enough 
information available to the user. The term user-friendly is applied to 
programs which have sufficiently clear and precise instructions to tell 
someone who has never seen the program running exactly what to do. 
We should always attempt to make our programs at least reasonably 
user-friendly. To continue the example of running a program again, 
the line: 

60 PRINT “AGAIN?” 
could be followed by 
70 INPUT A$ 


80 RUN 

or 

70 IFINKEY$ =" " THEN GOTO 70 
80 RUN 

Or 

70 IFINKEY$-'''' THEN GOTO 70 
80 IF INKEY$ =" Y" THEN RUN 
or 

70 PAUSE 40000 

90 RUN 


These need different responses. We should use for the first “PRESS 
NEWLINE (ENTER) TO RUN AGAIN”, for the second and fourth 
"HIT ANY KEY TO RUN AGAIN”, for the third “AGAIN? 
(PRESS Y OR М)” or similar instructions appropriate to the program. 

We can assume that the user recognises that an input prompt 
requires string or numeric input, according to its form, but (as we shall 
see later) there may be reasons for requesting a number in string form, 
and in any case we must make it clear what is required. We should be 
careful to use, for example: 


“INPUT FIRST WORD" andnot “INPUT AS" 
"ENTERA NUMBER 1 ТО 10° andnot “INPUT X” 
"MONTH (1 TO 12)" апа not “MONTH?” 


since if the user does not know what A or A§ are in the context of the 
program he or she is unlikely to respond correctly, and might try 
entering JAN or MARCH for the month. 
We should also avoid the use of instructions grouped together: 
10 PRINT “INPUT CURRENT, P.D, KNOWN AND 
UNKNOWN RESISTOR”’ 


394 


20 ІМРОТА 


30 INPUT B 
40 INPUT C 
30 INPUT D 


14 DIM A(10,3) 

20 PRINT “INPUT MATRIX” 

30 FOR F= 1 TO 10 

40 FOR N= 1TO3 

50 INPUT A(F,N) 

60 NEXT N 

7/0 NEXTF 
It is very easy for the user to forget which of the inputs is currently 
required. The information also fails to include the units of the values 
required, and does not print the input values on the screen. We should 
use a format like this: 


10 PRINT “INPUT CURRENT IN AMPS” 


20 INPUT A 

30 PRINT “CURRENT = '; A“ AMPS” 
49 PRINT “INPUT P.D. IN VOLTS” 

50 INPUT B 

00 PRINT "Р.О = “ Be" мо" 


This provides both clear instructions and visible input values. 

A look at any reasonably complex user-friendly program will show 
you that a significant portion of any application program is 
instructions. Instructions should be concise, but only to a degree that 
still provides adequate information. 

Expanded instructions can form part of the documentation of a 
program, but the program itself must contain the basic instructions 
required to ensure correct input and manipulation. 

The program ‘‘MATMULT”’ in the program library has a better 
approach to the array entry problem. Try to write one yourself, then 
compare the two routines. 

The combination of good instructions and input checks is the best 
method of reducing user error. The human being is less reliable than 
the computer, and far more inaccurate results or program crashes 
occur due to input error than happen due to bugs in the program, 
assuming it has successfully completed a sequence of dry runs. 

Checks to reduce the possibility of human error, or prevent bad 
effects from it, are the means by which a program is ‘idiot-proofed’ or 
‘mug-trapped’. Commercial programs designed for inexperienced 
users with no programming knowledge often have as much space 
devoted to input checks as to the program proper. We can assume some 
awareness in the users of our programs, and trust that they will enter 2 
and not TWO, for example, but check routines can ensure that simple 
keyboard errors are not passed over. Subtle errors or straightforward 
mistakes are less easy to deal with. 


3935 


It is a simple matter to check that an entered value is within an 

acceptable range: 

10 PRINT “INPUT MONTH (1 TO 12)" 

20 INPUTM 

30 IF M>12 OR M«1 THEN GOTO 10 
Since the month is to be input as an integer we could add a line to check 
this: 

40 IF INT M<>M THEN GOTO 16 

In fact one line will do it all: 

30 IF INT M<>M OR М>12 OR М<1 THEN GOTO 10 
Note that if there is an error, using GOTO 10 rather than GOTO 20 at 
least indicates to the user that something has happened by re-printing 
“INPUT MONTH (1 TO 12)” on the screen. If we used GOTO 20 
the user would wonder what had happened, and maybe think that the 
year was now required. It is better to have a statement specifically 
stating that there was an error in input. To continue our example, we 
could have these lines: 

30 IFINTM-M AND М< = 12 AND M» = 1 THEN GOTO 60 
40 PRINT “INPUT ERROR:RE-INPUT MONTH' 
50 GOTO 20 
60 PRINT ''INPUT YEAR (AS 82 FOR 1982, ЕТС.)” 
‘errr (Rest of program) 
The user is informed what is wrong, and told what to do. Make sure 
you see why the new line 30 had to have both the relational and logical 
operators switched round to make the program work. 

To enable re-use of check or error routines it is convenient to place 
them in subroutines. The following date entry routine uses a 
subroutine to print an error message for a few seconds (line 500) which 
is used if any of the checks shows an error. The routine checks the 
following: 

i) Day of month between 1 and 31 (line 40) 

ii) Month between 1 and 12 (line 90) 

ш) Year between 1911 and 1998 (line 140) 
iv) Whether the year is a leap year, and if it is not, that 29 February 
has not been entered (line 190) 
v) That days which do not exist in some months have not been 
entered (line 210). 
Check the logic used in these lines to see how it works. The lines are 
good examples of how multiple conditions can be combined, but for 
that reason they are a little difficult to follow. 


10 PRINT “ENTER DATE" 

20 PRINT "DAY?" 

38 INPUT D 

40 IF D»-1 AND 0<=31 THEN GOTO 
70 

58 GOSUB 500 

68 GOTO 20 

70 PRINT “MONTH? (1 TO 12)" 

88 INPUT M 


356 


90 IF М>-1 AND M<=12 THEN GOTO 
120 

100 GOSUB 500 

110 GOTO 70 

120 PRINT "YEAR? (AS LAST 2 DIG 
115)" 

130 INPUT Y 

140 IF Ү>10 AND Y<99 THEN GOTO 
170 

150 GOSUB 500 

160 СОТО 120 

170 REM *CHECK DAY US MONTH* 

180 REM *LEAP YEAR* 

190 IF INT (Y+1900) /4) <> (ү+190 
0) /4 AND М-2 AND D=29 THEN 
GOTO 220 

200 REM *SHORT MONTHS* 

210 IF NOT ((M=2 AND D>29) OR ( 
M=4 OR M=6 OR M=9 OR M=11 A 
ND D= 31) THEN GOTO 240 

220 GOSUB 500 

238 GOTO 19 

240 REM .....PROGRAM 

250 PRINT D;"/";M;"/19";Y 

268 REM seoses 

278 REM «se cue 

400 GOTO 999 

499 REM **ERROR NOTICE** 

500 PRINT "***INPUT ERROR***"," 
PLEASE FOLLOW INSTRUCTIONS" 
, RE-INPUT REQUESTED DATA". 

510 PAUSE 200 

520 CLS 


530 RETURN 
999 REM*END* 


The program ‘‘INDATE”’ in the program library uses much the same 
routines, but set up as two nested subroutines, so that it can be used in 
any program requiring multiple date entries, such as an accounting 
program. 

It is also a simple matter to put in input checks that print the input, 
and invite the operator to check if it is correct, and to re-input if an 
error has been made. This is important where multiple data entries are 
being made, since an error would otherwise require entering 
everything again. As an example, here is a check routine for string 
input: 


40 FOR N = 1 TO X 

50 PRINT "INPUT STRING";N 

60 INPUT WŠ (N) 

70 PRINT W$ (N) 

80 PRINT "IF INCORRECT PRESS E 
TO RE-ENTER."; TAB 0; "PRES 
S ANY OTHER KEY TO CONTINUE 


IF OK." 
99 IF INKEYS -"" THEN GOTO 99 
100 IF ІМКЕҮ5 = "E" THEN GOTO 5 
0 
110 NEXT М 


397 


Rather than check each value, it is sometimes better to wait until all 


entries have been made, 


and then print them out for checking. This 


routine does this for a list of numbers: 


10 


REM INPUT SPRINT» СНЕСЕ AND C 


ОРЕЕСТ ROUTINE FOR LIST 


20 
190 
200 
210 


220 


PRINT “ENTER NUMBERS" 

DIM ACz4) 

FOR L=i TO 24 

INFLUIT ACL) 

PRINT AT 3+L-12*(L312)510%( 


(2199? АС 


230 NEXT L 

200 FRINT АТ 21:07 "ALL CORRECT? 
CY ПЕ М3" 

210 INFUT ES 

320 IF E$z"Y" THEN GOTO 1000 
330 CLS 

340 PRINT "EACH VALUE WILL EE F 


FAINTED"; "ENTER NEWLINE IF ik. NEW 
VALJE", " IF WRONG, " 


350 


22,0 


1000 


ЕПЕ Ғ-1 TO 24 

FEINT АТ 21,;07ACF3) 
INFUT N$ 

IF N$z"" THEN GOTO 410 
LET ACF3= VAL N$ 

FEINT АТ 21sO07ACF3;3" 


SCROLL 
NEXT F 
REM *REZT OF FROGRAM* 


Spectrum users should delete line 410, inserting 410 POKE 23692, - 1. 
The virtue of using string input is that instead of stopping the program 
with an error message if an invalid entry is made (a letter, character 
that is non-numeric, or more than one decimal point), as occurs with a 
numeric input, the string input can be accepted whatever the 
characters input. The inputted string must be checked, however, or 
else we just get an error message when using VAL to convert to a 
numeric value. This requires a routine like the following: 


REM "STRINGNUM" 

PRINT AT 0,5; "ІМРОТ NUMBER" 
INPUT NŠ 

LET DP=0 

IF NS="" ‘THEN GOTO 100 

FOR Е=1 TO LEN NS 

IF CODE N$(F)«27 OR CODE NŠ 
(F)>37 THEN GOTO 100 

IF CODE N$(F)-27 THEN LET D 
P=DP+1 

NEXT F 

IF DP>=2 THEN GOTO 100 
GOTO 130 

PRINT AT 0,5;"ERROR IN INPU 
{н 

PAUSE 75 

СОТО 1@ 

REM ...REST OF PROGRAM.... 
SCROLL 


358 


150 PRINT VAL NŠ 

168 GOTO 10 
Spectrum users need to change the character code checks in lines 60 
and 70. Change 27 in line 70 to 46. Change line 60 to read IF CODE 
N$<46 OR CODE N$ = 47 OR CODE N$>57 THEN GOTO 100. 
Change line 140 to read 140РОКЕ 23692, — 1 and line 150 to read 150 
PRINT АТ 21,6;VALN$. 

Line 20 inputs the string. Line 30 sets a variable to store the number 
of decimal points. Line 40 checks that NEWLINE (ENTER) alone was 
not pressed, and passes control to line 100 to print an error message if it 
was. Lines 50 and 80 set a loop for the number of characters in N$, and 
line 60 uses CODE to check whether characters other than numbers 
and the decimal point are present, and goes to 100 for an error message 
if they are. Line 70 adds 1 to the variable DP for each decimal point 
found in N$. After the loop, line 90 sends control to 100 for an error 
message if there is more than one decimal point. Line 95 bypasses the 
error routine, and line 150 uses VAL to return the number for 
printing. At this point, if the number were needed for calculation, a 
variable could be set (LET N = VAL N$) to store the value. 

Note that an input error causes (line 120) the input routine to be 
repeated, after indicating for 1% seconds that an error exists. 


V3: Example Programs 


This Unit presents some examples of applications programs of various 
types, as follows: 


1 “КЕАСТ”: Reaction time testing. 

2 *BINGO'': Creation, calling and checking the cards for playing 
Bingo on the computer. 

3 “REF. INDEX”: The calculation of refractive indices from the 
angle of deviation and prism angle data produced by 
spectrometer experiments. 

4 “SERIES”: The summing of a convergent series to a given 
degree of accuracy. 

5 “СКАРН”: Calculation and plotting of functions, with titles 
and scales, to give a hard-copy printout. 

6 “ELEMENT”: The calculation of empirical chemical formulae 
from the percentage composition of compounds, or the 
percentage composition from the numbers of atoms of each 
element in the molecule. 

7 ‘*CASSFILE’’: Cassette file storage and manipulation, with 
printout of cassette files and cassette label printing. 


None of these programs are particularly complex (although CASSFILE 


is lengthy), and they deal with fairly straightforward applications. 
However, the principles involved are valid for any size of program, and 


359 


the programs themselves demonstrate many of the techniques and 
procedures introduced earlier in the text. More examples of 
applications programs and useful subroutines are to be found in the 
program library provided in the Appendix, but they are not as fully 
annotated. The programs here are presented as problems and 
solutions, with some discussion of the approach to the problem. The 
procedure is then presented, and the derived program. 

Please remember that any program can be written in different ways, 
even given that the algorithm is exactly the same. This variety of 
solutions means that there is never only one correct program. 

Spectrum users should note that we have indicated some instances 
where the additional functions of the Spectrum can be put to use. 
These functions are described in the next Section. After you have 
explored the new functions, you should return to these programs and 
modify them for practice in the use of these facilities. 


1. “REACT” 


Problem: To use the computer to assess response times in reaction to a 
signal. An average should be taken of a number of timings. 
Research the problem: The timing function can use the system 


variable FRAMES. A start signal will be required, which should be 
preceded by a random delay to prevent anticipation. Computing time 
must be allowed for in the result. The number of timings desired 
should be input and used to set up a loop. 

On the ZX81 FRAMES is a system variable held in 2 bytes, 16436 
and 16437. On the Spectrum it is 3 bytes, 23672, 23673 and 23674. 
The program can use both bytes on the ZX81 and the two less 
significant bytes (the first two) on the Spectrum (since we do not need 
to time hours!) This will give a timing period of up to 
((256 x 255)  255)/50 seconds in the U.K. and ((256 x 255) + 255)/60 
seconds in the U.S., or about 22 and 18 minutes respectively, before 
the FRAMES counter, which counts backwards by decrementing by 1 
every 1/50 (or 1/60) seconds, reaches zero. This will allow the program 
to be used as a timer for longer periods, or modified for use as a 
stopwatch program. 

Procedure: The program will have a loop structure, determined by the 
input of the number of tests required. Outside this loop will be the 
instructions at the beginning of the program, and the output of average 
reaction time. 

This timing module is the core of the program. The input module 
(instructions, ‘get ready’ messages and an input for the number of 
timings required) and the output module (average time) are easily built 
around this. We may proceed to code in a version of this module, 
having decided our structure for the program, and test/debug the 
timing module, before using the editing facilities to modify this module 
as required and code in the input and output modules. 


360 


The timing module will require the address bytes to be set at a 
known value (the maximum, 255) by POKEing values in, and the 
values returned by PEEKing these bytes will be used to calculate the 
time according to the expression T -((256*(255 - PEEK 
16437)) 4 255 - PEEK 16436)/50. (U.S. users must use 60, not 50 in 
the expression and the program.) For the Spectrum the first address 
will be 23673 and the second 23672. 

Our procedure in this simple linear program is as follows: 


1 Input Module = 1 Give instructions 

2 Input number of tests required (A) 

3 Initialise array for timings, B(A) 

4 [Initialise variable for total timings, X 
5 


Initialise FOR - NEXT Loop (1 TO A) 


Ш 
фа 


2 Timing Module Give “рес ready’’ message 

2 Provide random delay to prevent antici- 
pation 

3 Set timing function by POKEing 255 into 
the FRAMES addresses 

4 Give signal 

5 Walt for key to be pressed 

6 Calculate reaction time. Allow for 
computing time 

7 Store result as B(A) 

8 Add B(A) to X 

9 Repeat 1-8, A times 


3 Output Module = 1 Calculate average reaction time 
Print average time 


The timing module could be coded, run and tested as follows: 
Timing Module Program Listing 


1 REM REACT CORE FROGRAM 

120 PRINT "-ON YOUR MARKZ-" 

170 PAUSE 75 

120 CL 

190 PRINT “<GET SET?" 

200 FOF L=0 TO END #35006 

210 NEXT L 

220 БОКЕ 16436:2955 

230 PORE 1564373295 

240 PRINT АТ 10510; "*Güx«" 

250 IF ІМКЕҮ% ="" THEN GOTO 250 
260 LET T=(255- PEEK 164362/50-4 
(256%(259- PEEK 1649372) /50-0. 12 
270 PRINT “REACTION TIME ";T;" 
SECONDS" 


Spectrum users should note the problem with INKEY$, and the fact 
that we cannot use PAUSE @ since the PAUSE instruction uses 


361 


FRAMES also. The solution is to use the ENTER key as the key to be 
pressed. Change line 250 to INPUT A$. As long as only the ENTER 
key is used, this works. Change .12 to .03 (the time allowed for 
computing) in line because of the faster response of the Spectrum. 
When satisfied that the timing module works, we go on to code in the 
rest of the program, editing any changed lines. (Only 260, since we 
kept the same numbering.) You would have to change line numbers in 
developing the program, unless you coded your program accurately 
with line numbers before keying anything in. 
For the Spectrum, modifications are required in the following lines: 
200 FOR L = 0 TO RND * 1000 
220 РОКЕ 23673, 255 
230 POKE 23672, 255 
260 LET T = (256 * (255 - PEEK 23673))/50 
+ (255 - PEEK 23672)/50 - .03 
If there are problems with the INKEY$ operation on the Spectrum (as 
we noted earlier, it doesn't always work), the program should be 
modified to: 


1) Instruct the user to hold his finger over, then press the ENTER 
key (lines 60 and 70). 

i) Change line 250 to read INPUT A$. The null string will then be 
entered when ENTER is pressed and the program will go to the 
next line, to derive the reaction time. 


Users in the U.S. must replace the 50 which appears twice in line 260, 
by 60 to get an accurate timing result. 

Spectrum users can use the DEF FN, FN functions for timing. See 
the Sinclair Spectrum manual, Chapter 18, for a good description of 
this method. 


362 


Flowchart “ВЕАСТ” 


PRINT 
INSITRUC- 
TIONS 


INPUT 
TESTS 
REQUIRED 


SET ARRAY 
B (A) 





363 


| 








SET 
TIMING 
VARIABLES 





ADD TIME 
TO X 


364 


Program listing 


S REM "REACT" 

10 PRINT “REACTION TEST" 

zü PRINT "à3xcx3*3 3€ 33 9€" 

30 PRINT 

40 FRINT "THE SCREEN WILL SHOW 
ñ пи GET ZET "utu " 

SO PRINT “MESSAGE. PLACE A FING 
ER OVER" 

60 PRINT "THE ""R "" KEY. WH 
EN xGÜx* AFFPEARS" 

70 PRINT "FRESS Е. EACH REACTIO 
N TIME AND" 

SO PRINT "THE AVERAGE WILL EE 
DISFLAYELD" 

70 PALISE 200 

100 FRINT »s "ENTER NUMBER OF TE 
STS REQUIRED" 

110 LET X=0 

120 INFUT A 

130 DIM ECA) 

140 PRINT 

142 FEM 

xxTEZT LOOP 


150 Fok N-1 Tü A 

140 FEINT "-ON YOUR MARKS-" 

170 PAUSE 75 

120 CLE 

190 PRINT "GET SET?" 

200 FOR L=0 TO ЕМО #500 

210 NEXT L 

215 КЕМ 

+*5ЕТ TIMER EBYTES** 

220 РОКЕ 1643732559 

230 РОКЕ 16426%255 

240 PRINT АТ 10310: "*G0%" 

250 IF INKEY$ ="" THEN GOTO 220 
260 LET Е(М2-(256%(255- РЕЕК 16 
437) )/50+(255- PEEK 164362 /50-0. 
14 

270 PRINT "REACTION TIME ":ECN2 
s" SECONDS" 

280 LET X=X+E(N) 

290 PRINT “PRESS NEWLINE/ENTEF 
TO CONTINUE" 

300 INPUT АФ 

310 CLS 

320 NEXT М 

329 REM 

*##ENDLOOP ++ 


230 PRINT 
340 PRINT "AVERAGE TIME WAS "FX 
/A;" SECS" 
350 STOP 


360 REM жЖЕМПжж 


365 


Comments: The use of an array (B(A)) gives us the flexibility to add 
further manipulations (full printout or standard deviation, for 
example) if we wished, by adding a further module to the program. 
We could use the same principle to time other processes. The 
accuracy of the allowance for the delay due to computing time becomes 
less important as the time being measured increases. To derive a stop- 
watch program (timing less than 65535/50 secs — about 21 minutes in 
the U.K.) we would need a start and stop routine, built around the 
POKE and PEEK lines. Write such a program. Notice how the 
program is set so that the computer waits until a key is pressed in line 
250. Remember we cannot use PAUSE in the form of PAUSE 40000 
(ZX81) or PAUSE 0 (Spectrum) since that uses the FRAMES system 


variables also, and would reset the timer. 
2. “BINGO” 


Problem: In the game of BINGO the caller shouts out the numbers 
between 1 and 99 in a random order and each player has a card with a 
set of numbers (say 15) in this range. The cards for each player contain 
different sets of numbers. The winner of the game is the player whose 
list of numbers is called first. 

The program should play the game for up to four players and check 
the validity of the winning player's card. 


Outline Procedure: Modules are required as follows: 
1 Set up game 2 Play game 3 Result of game 
Procedure will be as follows: 


Write preliminary instructions 

Set up caller’s numbers 

Set up players’ numbers 

Display players’ numbers 

Display caller’s numbers (one at a 
time) 


МЮ = к. ке e 
— +> GO N н 


2.2 Allow interruption by player 
3.1 Display players’ numbers 
3.2 Display numbers called 

3.3 Check winning card 


1.1 These are the instructions needed to start the game. At each stage 
in the program it is essential to give clear directions to the user on 
how to proceed. 

1.2 ‘The caller's numbers require a random list of the integers 1 to 99 
(each number occurring only once) which will be put in array 
А(99). 


366 


1.3 





The players` cards require 4 sets (cards) of 15 random integers in 
the range 1 to 99 (i.e. different numbers). The cards should have 
an ordered list of numbers and each list is a different set of 
numbers. These will be put into arrays O(15), R(15), S(15) and 
T(15). 

Display the players’ cards on the screen and allow time for the 
players to take down the numbers. 

Display the caller’s numbers one at a time on the screen in large 
form. 

Allow the display to be interrupted when a player calls ‘house’ 
(i.e. thinks that all the numbers on his card have been displayed). 
Repeats 1.4 for players to check their numbers. 

The numbers called (i.e. those actually displayed in 2.1) are 
sorted into numerical order (and put into array P(99) which 
contains between 15 and 99 numbers) and displayed on screen. 
The ‘winning’ card is selected and the numbers on this card are 
put into the array V(15). These numbers are then compared with 
the numbers called [in P(99)] to check that they are correct. 


Algorithm Description 


1.1 


This section gives the minimum instructions required to play. 
You may want to key in fuller details of the game of BINGO. 
(Lines 10 to 110 in program). 


1.2 Set up caller's numbers 
Flowchart: 








INITIALISE 
ARRAY 





This routine starts at line 120, clearing the screen and going into fast 
mode on the ZX81 for the calculation. The above routine is contained 
within the caller's numbers subroutine (lines 2500 to 2590), but note 
this could be a subprogram sequence as part of the main program as it 


Is only executed once. 


1.3 Setting up (the BINGO cards) 


Flowchart: 


DIMENSION 


ARRAYS 





FOR EACH 
NUMBER 
ALREADY 
CHOSEN 





368 


FOR 
EACH 


CARD 
FOR 15 
NUMBERS 
LET Y = @ 
GOSUB 


SORT 


GOSUB 


ARRAY 
CHOICE 





In the program this routine begins at line 320. Note array P(99), which 
is used in the sorting routine (although containing only 15 numbers) 
and is then used again later for the caller’s numbers. 

Lines 480 - 540 carry out the selection of the 15 random numbers. 
Subroutine 3000 — 3170 is the sorting routine which is the SHELL 
SORT given in Section T. (A fast sort is needed as at a later stage we 
are sorting nearly 100 numbers.) 

Subroutine 3500 — 3560 puts the numbers into the appropriate 
array. 

1.4 This subroutine (lines 1600 - 1650) displays the numbers on the 
cards in a tabular form. 
2.1/2.2 Display caller’s numbers and interrupt if ‘House’ is called 








оо O2 
М mi 


З.А 


This subroutine takes numbers generated апа (in FAST mode оп 
the ZX81) displays them 16 times their normal size and places 
them in an array P. Variable Z counts the number of numbers 
called. At the end of this subroutine the numbers called have 
been put into the array P (which will contain Z numbers). 
This repeats step 1.4. 
This routine (lines 960 — 1070) calls a sort subroutine at line 3000 
which sorts the list P (Z) into numerical order and prints them out 
on the screen. 
This subroutine (lines 4000 — 4260) has two parts. 
(1) Select the ‘winning’ card and arrange for the ‘winning’ list 
of numbers to be put in the array V(15) (lines 4000 - 4120) 
(2) Check the numbers on the ‘winning’ card. It is necessary to 
search the ordered list P containing Z numbers for the 
numbers in the ordered list V containing 15 numbers. If any 
number is missing the card is not complete. If all numbers 
are present then CONGRATULATIONS is printed. 
The quickest search method is as follows: 
Search for V(1) in list P until it is found, say P(12). 
Search for V(2) in list P beginning at P(13) etc. 
The search will end as soon as a number in list V is not in list P 
but will continue for all 15 numbers in list V if they appear in list 
P. The flowchart for this search is as given below: 


370 


COUNTER FOR 













LIST P 
N=] COUNTER FOR 
N>15 LIST ү 
PRI 
V(N) 
CORRECT 
LET 
M = M+] 
CHECKS IF 
NUMBERS IN 
LIST.P 
FINISHED 





COMPLETE 


RETURN 
E 2 TO GAME 











PRINT 
СОМСААТ- 
ULATIONS 


STOP 


371 


Data Table 
The following variables are used: 
Q(15), R(15), S(15), T(15) are the arrays containing the players 
numbers. 
A(99) is the array containing the numbers for the caller. 
P(99) is the array containing the numbers actually called, and is also 
used as a temporary storage in setting up the players’ numbers and in 
the sorting routine. 
X is a random number between 1 and 99. 
Z is a counter for numbers called. 
Y is the number of elements present in an array to be sorted. 
V(15) is array containing ‘winning’ list of numbers. 
B$(99,2) is an array containing the string values corresponding to the 
elements in P(99). 
C is the character code of second character in element of array B$. 
D is the character code of first character in element of array B$. 
M is the counter for array P in the ‘check numbers’ section. 


Comments: If you wish to play with your own BINGO cards and let the 
computer be the caller only, then you can delete modules of the 
program as follows: 

1.3 Set up players’ numbers 

1.4 Display players' numbers 

3.1 Display players’ numbers 

These latter two modules are the same subroutine. You could also 
revise the program and include, as an option in the user instructions 
routine at the beginning, the choice of the two different modes of play. 


Spectrum modifications: 


Delete Lines 290 and 585. 

Change Line 660 to 660 PAUSE 0 

Delete Line 830 

Change line 800 to 800 FOR F = 1 TO 400 

Edit line 810, renumber as line 805, to read 805 IF INKEYS$«»'' ”’ 
THEN GOTO 830 

New line 810 NEXT F 

Note: This sets up a FOR - NEXT loop to contain the reading of 
INKEYS, to make this operation of checking to see if someone's bingo 
card is full more reliable. The delay of a 1 TO 400 loop is about two 
seconds, the same as the PAUSE in the original program. 

Edit line 835, renumber as line 830, to read 830 CLS 

Delete line 835 

Change line 980 to PAUSE 0 

Delete line 1005 

Delete line 1025 

Delete line 5010 


372 


Change line 5070 to 5070 LET E = PEEK (15360 +8*C +R) 
Change line 5200 to 5200 LET Е = PEEK (15360 +8*D +R) 


Flowchart ‘BINGO’ 


START 






PRINT 
INSTRUCT- 
IONS 


PAUSE 









PRINT 
NUMBERS 
CALLED 





PAUSE 


STOP 


SELECT 
NUMBERS 






GOSUB 
BIG PRINT 


BINGO 
CALLED 


212 


Program Listing 


2 GEM SS NGO” 

10 REM RRR KR ХХХ OY HERE 
%1, 36% INSTRUCTIONS % 
XX 3e XXE EE ЖЖЖ ЗРЗЕ ЭЗЕ 

20 PRINT TAB 10; "BINGO": TAE : 

ох ыы 

30 PRINT |+ É "SOUR EINGO CARDS A 

RE PRODUCED" 

40. PRINT 99 "А5 THE LISTS "" WQ 
ни 4 ип A пи ' ы" Өт ТЕГ] AND "H" n 
T пи и 

20 PRINT »+"THEY ARE СОСОРТЕП 71) 
А PRINTER" ++, "TF CONNECTED, OTHE 
RWISE YOU MUST" 
60 PRINT so "NOTE DOWN YOUR CHO 
SEN LIST WHEN" 
70 PRINT |+ + "THEY АРРЕАР, NOTE T 
HE LETTER ALSO” 

ШО PRINT »% “WHEN YOL ARE READY 
FRESS ANY KEY" 

70 PRINT || "TO START. THERE WIL 

L BE A DELAY" 
100 PRINT |, "WHILST THE NUMBERS 
ARE SET UP," 
110 IF INKEY$ ="" THEN GOTO 110 
120 CLS 
200 RAND 
290 FAST 
200 REM 33433 C HHH Ж 
*1; Z«*SET UP CALLERS x 
* NUMEE Fs: x 
Хх ЖҰ Ж 
210 DOSJE 2500 
320 REM 3J4333X34X3 3 € 3€ (XC C969 3 3 X. 
*1.cXSET UP PLAYERS * 
* NUMBERS * 
3X 3C 3C 3C3C 33€ 3E 3€ 3E KH 553 
420 DIM acis) 
430 DIM Есі) 
440 DIM 5(1©®) 
450 DIM Tc183 
4640 DIM P(9?93 
470 ЕСЕ W=1 TO 4 
430 FOR J=1 TO 15 
490 LET X= INT (7 
500 FOR Isi TO J-1 
510 IF XzsP(I2 THEN GOTO 490 
220 NEXT I 
S90 LET PGJ»zX 
540 NEXT . 
550 LET Y=15 
ESO GÜSLE 3000 
570 DOSIJE 3500 
280 NEXT U 
seo SLOW 
S70 PRINT 
600 FRINT 
610 REM XXX 33333 33 M EE 364396 
#1, 48 DISPLAY PLAYERS ж 
ж NLIMBES ж 
ХХХ 
DOSJE 1600 


DG. 
э 
LI e 


374 


& 30 


640 
850 


REM **L IST COPIED IF жж 
жж PRINTER жж 

COPY 

PRINT »» "PRESS ANY KEY TO F 


ROCEED" 


EGO 
670 
650 
THE 
EPO 
700 


IF INKEY$ ="" THEN GOTO 660 
DLE 

PRINT "THE CALLER WILL GIVE 
NUMEERS ONE AT A TIME" 
FRINT 

PRINT "WHEN YOUR CARD 15 cU 


MPLETE PRESSANY KEY WHEN NUMBER 
IS ON SCREEN" 


710 
720 
CEED" 
730 
732 


740 


745 
720 
755 
760 


PRINT 
PRINT “PRESS ANY KEY TO РЕС) 


IF ІМКЕҮФ ="" THEN GOTO 730 

CLS 

REM 3333 3 3 X X X € ЗЕ M 
+2. 1% PRINT OUT CALLS x 
HHH HH HHH EE EE EE HE 

LET Z=1 

DIM Beers, 2) 

CLS 

PRINT " PRESS ANY SEY WHEN 


YOUR CARD IS COMPLETE” 


770 
750 
790 
793 


200 


210 
=O 


я Е 


CS du 
220 
S20 


[жа есі = 


240 


S50 


EINE ЖЫ 


S40 
270 


2120) 


890 
200 
910 
920 
730 


935 


940 
745 


250 


ЕКПЕ N=Z TÜ 99 

Güzim] Sooo 

LET FCN) =ACND 

PAL'SE 200 

REM 33 3 3 9€ 303€ 9€ 3€ 9€ 30 3€ 3E 3E 3E CE CE E 
#2. Z2XPLAYER INTERRUPT ж 
HH 3CCC JC 3C Хы 

IF INKEY$ <> "" THEN GOTO & 


LET Z=Z+1 
NEXT N 
LW 


| L LZ 


FOR N=1 TO 10 
PRINT ТАБ N:"Z«*BINGUÜUS-ZXEIN 


NEXT N 

PRINT Өз “CHECK YOUR CARDS" 

REM 3C 3C 36 36 3: 3€ 3€ 9€ 9€ C Хы Ж 
яз, 1*DISFLAY PLAYERS ж 
* NLIM RER © % 
ХХХ 

РАЦЕ 100 


LET Y=Z 

PRINT “YOUR NUMBERS WERE" 

PEINT 

REM X33534 3333333 M EE SE ARERR 
ЖРБІМТ QUT CARE NUMBERS + 

GIJE 1600 

FEM 

FEM жж Хы 3E 9C ы Ж 
X. ZXDISPLAY NUMBERS ж 
* CALLED * 
Y X 3C 3€ 3C CC 555555553553 


375 


260 PRINT “PRESS ANY X БҰ TO GET 
LIST ОЕ", "THE NUMBERS CALLED. " 
1270 PRINT "THERE WILL ре А SHOP: 
T DELAY FOR SORTING, " 

9780 IF INKEYS ="" THEN GOTO F20 


we cl © 


1008 FART 
1010 pne zi oc 
1020 ELS 


TOFS SLOW 

1030 PRINT "CALLERS LIST" 

1040 PRINT 

1050 FOR Nel TO Z 

1060 PRINT РМ" "3 

1070 NEXT N 

1050 PRINT 

LOSE REM HREM ERR EER EE HEH REALE EH 
#3. JW CHECK WINNING X 
ж MARI * 
XE 3 XXX XC ЖЖ 

1070 GÜSLUE 4000 


1100 LET 2=2+1 

1110 PRINT ++ "DO YOU WISH TO CON 
TINUE THE GAME? CY/N3" 

1420 INFET CS 

1120 IF C#="N" THEN STOP 

1140 IF Ce="¥" THEN GOTO 755 
4450 PRINT "INPUT Y OR N ОМЕР. 
FASE" 

1160 GOTO 1120 


11920 REM J3XX33 0 (4 0 Хы 
ж END PROGRAM x 
X XC 34 АЕ 3E EXC OE EXE EE EEK at 
1200 STOF 


1210 КЕМ 


| EDO REM жұ АЖ 
x SURO TT NES ж 
ХЕҰ XE COE Ж 

15920 КЕМ 

AOG Б ЕМ ж EXE CE EE EK EH 
ЖЖСӘМБЕЕПШТІМЕ TO PRINT ж 
AOUT PLAYERS CARLS + 
HH HHH HE HE EE EE 6 


“410 PRINT "Ga": TAB 6: "8S"? ТАР і 

ев: TAB Ter *t* 

4620 FOR ті TO 45 

2420 PRI NT Gc.5; TAE &G:RCZo0: ТАЕ 
iz:m620: TAB Ler Сш 

1440 NEXT 4 

TESO RETURN 


1660 REM жж МОЛ жж 
Хх ЖЖЖ ы 

2470 REM 

SIO) БЕМ eM HE EH 
#*#¥5UCREOUTINE TO SET жж 
XXCALLERS NUMEBERZ Xx 
FEE ЖЖ EEE 

того DIM ACHD) 

2240 FOR Net TO PP 


376 


ore as. 

2520 
2570 
2580 
2590 


29850 


S000 
2010 
32030 


2040 


S080 
S060 
3070 
TOSO 
S070 
3100 
3110 
2120 
2120 
2140 
3150 


21680 


2190 
3470 


2500 
3510 
3220 


3530 


t ul el 
3540 
3550 


3&0 


3870 


4000 
4010 


4020 


зуу 


IF ACX) <> 0 THEN SOTO 2550 
LET АсХ>= 

NEXT N 

ЕЕТМЕМ 


LET X= INT (99% RND 2-1 


М 


REM жж ENDHI X% 
X33 ЕЕЕ HR KEKE XXE CX 


КЕМ 303 3 9 0 € CE HHH HH Ж 
X*SORT SUBROUTINE жж 
ж Ж ХХ 

LET S= 

LET S= INT (S/2) 

IF Š >= 1 THEN GOTO 2050 

GOTO 3170 


FOR К=1 TO Š 

FOR AsK TO Y-S STEP K 

LET E=A 

LET TsP(A«2) 

IF T >= РСВ) THEN GOTO 2130 
г 


(ЕТ Ве-В-< 
IF В >= 1 THEN GOTO 3090 
LET P(B+S)=T 


GOTO 23010 
RETURN 


REM жж  ENDSUE + 
HHH HH RIK REE ЕЕ ЭЕ ЗЕ KRK 


REM 

fet LF ХХХ EE 3C YE 
S## 5G ROUTINE FoR КОМБ» 
23 NUMBER ARRAYS жж 
JC X- 3€ 3C 3€ 3C 3€ 263 3 3E ЭРЭР 36 3E 3E HEH EHH EE 

1 70:12 


2/7 BL 

IF Ше1 THEN LET ос) =Р CJ) 
TF Uz2 THEN LET--R(Jy=P (J) 
IF Нез THEN LET SCAOD PCI 
IF l4 THEN LET Tc PG) 


RETURN 


REM жж ENDSUE жж 
He KE SEE FEE EEE EEE EE E 


REM 

REMO ж ЖҰ ы 
ЖЖСШИБЕПИТІМЕ TO CHECK ae 
HX RESULTS жж 
363 4C 3C 3E JC XC 3C 3€ 0E ыж 

PRINT 

[REM 3 Xx 3C Ж ee OMO 
#3. 3. IX SELECT WINNING ж 
ж CART є 
HHH X3 HHH HH HH MOORE MOYO 

PRINT "ТҮЗЕ WINNING CARD (È 


T3 it 


377 


4020 INFUT АФ 

£040 IF AS <> "QU AND AS <> "m" 

AND АФ <> "S" AND AS <> "T" THEN 

GOTO 4020 

4050 CLS 

4060 DIM Vct&) 

4070 FOF N=1 TO 1% 

4080 IF Ag="h" THEN LET V(N)=m (N 

3 

4090 IF АФ=" 8" THEN LET VCNI=SRCN 

3 

4100 IF Ag="5" THEN LET V(N)=S (N 

E 

4110 IF A$z"T" THEN LET V(N)3=T (N 

) 

4120 NEXT N 

4195 REM хх 3XX XXX XC XXE 
#3, 2. ZXCHECK NUMBERS ж 
522222552222 52222 EY 

4130 LET М1 

4140 FoR Nzi To 15 

4150 IF V(N)=F(M) THEN PRINT VON 

Jj?" QURRECT” 

4160 IF VCNI=SFP CM) THEN GOTO 4200 

4170 LET M=M+1 

4120 IF M=Z+1 THEN GOTO 4220 

4170 GOTO 4150 


4200 NEXT М 


4210 GOTO 4245 


4220 PRINT “#CARD "FAG?" NOT COM 
PLETED»" 
4230 PRINT МОМ)?" NOT CALLED" 
42552 REM 

XGÜTO RETURN TO CONTINUE 


4240 GOTO 4260 


4245 PRINT »» TAB 47" жж CONGRAT 
ULATIONS жж "; TAE 45 "%%%%%%%%%% 
%%%%%%%%%"... "GAME ENDED. USE RUN 
TO RESTART" 
4250 REM 
жж GOTO PROGRAM END жж 


4255 GOTO 1200 
4260 RETURN 


4270 КЕМ жж ЕМПЕМЕ жж 
JC OC XC 3C JEFE AE 3C 3C ЭЕ ЭЕ ЭЕ ЭЕ ЗЕ ЭЕ ЭЕ ЭЕ ЭЕ ЭЕ ЭЕ ЭЕ XE 


4900 FEM 

SOOO REM ххх x * x X X HEH Хы HE 
*#*#SUBROUTINE GIG PFLOT** 
ee Ж 

2010 FAST 

2020 LET Е%(Мо- STR ACN? 

5030 LET C= CODE БФ(М2(1 TO 1) 

5040 IF LEN ЕФ‹М)© 7 THEN Goto 50 


eo 


378 


5050 
=060 
5070 
5020 
2090 
2100 

5110 


214 


2160 
2170 
5150 
2190 
= 


200 
5216 


=. » а 
` а а 


2220 
“2840 
s dad 
2250 
т270 


есес 

5290 
“Ооо 
AGIO 
A020 
GOTS 


z QAQ 


ë GS 


ё 872 С ) 


5070 


3. “REF. INDEX" 


Problem: In a laboratory experiment with a spectrometer, a series of 
measurements are made of the prism angle A and the angle of 
minimum deviation D for various prisms. The refractive index of each 


LET D= CODE E$CN» (2 TO 2) 
FOR R-O TO 7 

LET E= PEEK (7680+8xC+R) 
БЕТ W= 125 

FOR б=0 TO 7 

IF E<W THEN GOTO 5150 
PRINT AT 2#R+5. 2#G+17 E. 
PRINT AT 2ЖЕғ5.2ж041;" 
LET ESE-MW 


ЭТО 6:2?О 


PRINT АТ 2#®+5,2=5+1; 

PRINT АТ 2#К+6,2#%0+1;" " 
LET W=W/2 

МЕХТ б 

IF LEN B$%(N)<2 THEN GOTO 20 


LET F= PEEK (768048*D4R) 


FUR Н=0 TO 7 

IF F«W THEN GOTO 5280 
PEINT АТ 2жкесутжнеіс: "ШЕ 
PRINT АТ ZX*R-*53ZXH-915; ш. 
LET F=F-W 

UTO 4000 


PRI! Ba AT SHE PEEL A U Т 
PRINT АТ ZAR ty Zapia" u 


LET A J=1J / 2 
NEXT H 

NEXT R 

SLOW 

RETURN 

REM ж  ENDZLUE X% 


ж MEER 0€ 3C XC GE 


REM 
REM жж END PROGRAM LIST*x* 
HHH NEE HEH HAE EE EE EE 


is then determined using the formula: 


We require a table of results and an average of the refractive index 
results for each prism. Six prisms and four measurements for each 


Sin (A + D) = Sin (A) 
2 2 


prism are to be allowed for. 


Research the problem: Since we are using up to six prisms and each 
one can have four readings it is convenient to use nested loops and two- 
dimensional arrays to store the input. In this way A(3,4) can, for 
example, represent the third prism, fourth reading of prism angle. We 
will use lists to refer to the prisms and the quantities associated with the 


379 


prisms, so that, for example, Z(3) can represent the average refractive 
index of the third prism. 

Angles will be input in degrees. Since the formula for the calculation 
requires the use of the Sine function SIN, we will need to convert to 
radians. This will have to be done before the refractive index is 
calculated. We can provide a simple input check in a subroutine. Zero 
entries in the input loops will signify end of prisms or end of readings. 


Outline Procedure: 


1 Input: Data 
2 Calculate: Refractive indices and averages 
3 Output: Results in suitable tabular form 


Detailed Procedure: 


Dimension Arrays and Lists 

FOR each Prism (1 to 6) 

Set Z as zero 

Input Prism number 

If Prism = 0, GOTO 3.1 

FOR each Reading (1 to 4) 

Input Prism Angle 

If Angle = 0, GOTO NEXT Prism 

Input Minimum Deviation 

Convert angle to radians 

Convert minimum deviation to radians 
Calculate Refractive Index 

Round to 3 decimal places 

Add Refractive Index to Z 

NEXT Reading 

Average R.I.=Z divided by number of 
readings 

Let Average R.I. = Z(N) 

NEXT Prism 

Print Headings 

FOR Each Prism 

FOR Each Reading 

If Reading not 0, print Prism, Number, 
Angle, Minimum Deviation, Refractive Index 
NEXT Reading 

NEXT Prism 

Print Headings 

FOR Each Prism 

Print Prism Number, Refractive Index 
NEXT Prism 


Input null string if error, C if correct 


1 Input 


2 Processing 


NO NO NO NO ND DN N = = ка = Re eS = ке кә 
SOD Q + OO NK СО @ +I O OF > WO NH = 


3 Output 


оо шо бо бо м м 
+ O39 м = O оо 


+ 52 GO OO GO OO OO 
— ка (O Со SIO 0 
=< 


4 Correct 


380 


Error 4.2 Return 
Subroutine 


Note: 


Subroutine called after each input. All entries can be re-input if 
Incorrect. See program listing. 


Data Table 


Prism number 


A(6,4) Four Angles of measurement for each of 6 prisms 
D(6,4) Minimum Deviations, for each value of A(6,4) 


N(6,4) Results of refractive index calculation for each experiment, 


derived from the values stored in arrays A and D 

Variable to store totals of minimum deviations. 

Average refractive index for each prism, from the average of 
the four values stored in array N. 

Used as loop variables for input 

Used as loop variables for printout 

Used as input for error check subroutine. 

Null string if incorrect, ‘‘C’’ if correct. 


START 


DIMENSION 


Flowchart “REF. INDEX 


ARRAYS 










OUTPUT 
RESULTS 


STOP 

















INPUT 
PRISM 
NUMBER 





381 















INPU 
CORRECT 





CONVERT 
TO RADIANS 





CALCULATE 
R.I., ADD 
TO Z 





es 
No INPUT Yes PRISM 
CORRECT =ø 
No 
M = ] 


CALCULATE 


AVERAGE 
R.I, FOR 
PRISM 





382 


Program Listing 


= REM "REF. INDEX" 

10 PRINT "**xREFEACTIVE INDEX3* 
"soo “USING SPECTROMETER" 

20 PRINT ss "ALLOWS UP TO & PRI 
SMS AND 4 SETS OF READINGS FOR E 


25 REM *-*AVGE REF. IND. AEEAY** 
30 DIM Z¢4) 

35 REM **FFISMS ARRAY ** 

40 DIM Fé) 

45 REM ##*#FRISM ANGLE ARRAY *#* 
50 DIM Ас 4) 

59 REM ##*#MIN. DEV. ARRAY** 

60 DIM П(6з49 

ес REM ЖҰРЕҒ. IND. ARR AY** 

70 DIM N(65 43 

SO FEM жж ХЕ ЕЖ 
85 REM **INFUT DATA LOOF#+* 


90 FOR N=1 TO é 

100 LET 2-0 

110 PRINT "INPUT PRISM NUMBER» I 

МРОТ 0", "ТО FINISH" 

120 INFUT P (N) 

130 PRINT "PRISM NUMBER ";P (N) 

140 GOSLIB 700 

150 IF A$ <> "C" THEN GOTO 110 

160 IF F'(N)=O THEN GOTO 500 

165% REM J3HuUdciads €x ХЫ + 
X*START READINGS 100Ржж 


170 FüR M=1 TO 4 
180 PRINT "INFUT FRIZM ANGLE IN 
DEGREES: INFUT Ó TO FINISH" 
190 INFUT АСМ» M) | 
200 PRINT "ANGLE OF PRISM "АСМ 
M) 
710 GŪSIE 700 
220 IF A$ <> "C" THEN GOTO 180 
220 IF ACNsM)=0 THEN GOTO 410 
240 PRINT “INPUT MIN. DEV. IN DE 
GREES" 
250 INFUT DCN: М) 
260 PRINT "MIN. DEV. ";D(Ns M) 
270 GOSUE 700 
280 IF А% <> "C" ТНЕМ БОТП 180 
290 REM жжСПМУЕЕТ DEGREES Тож 
xxFEADIANZ жж 
300 LET А=АсМ, М) + PI /180 
310 LET D=DCNsM)* РІ /180 
220 REM *#REFRACTIVE INDEXs* 
230 LET М(МЭМо-( SIN ¢¢CAtD9/23 3 
/ SIN (6/2) 
340 LET МСМ. М) = INT CLOOO#NCNSM 
2%, 33/1000 
250 LET Z=Z+N(N; М) 
360 NEXT М 
270 REM ##END READINGS LOOP жж 
ХХХ Жы 
330 REM 
390 REM жжАУЕРАСЕ TO 2 DEC. ++ 
++ PLACES ++ 


383 


400 REM 

410 LET Z=Z/(M-13 

420 LET 7(Мо- INT (100%7-,52/10 
Ü 

430 NEXT N 

440 REM 

450 REM *#*ЕМП INFUT LOOP ++ 
460 REM >> X X3 (€ 3€ 
470 REM 

450 REM 34333 3 3 9 9 3€ 3€ 3€ 9€ 9€ 9€ 3€ 9€ 9€ 3€ 3€ 9€ 
470 REM ** PRINT CUT жж 
4952 КЕМ 

500 РЕІМТ "РЕІЕМ ж ANGLE ж MIN. 
DEV ж ЕЕ, ІМ. ЖЖЖ 33 3333 
JC 33 3€ 9€ 363€ 3€ 3C ыы. 

510 FOR Y=1 TO N-i 

520 FOR X=1 Tü 4 

S30 IF AcY¥YsX)=0 THEN GOTO 550 
540 PRINT FCY): TAB &;"+*+ "АСУ, 
Xd; TAE 143 "ж "#D(Y Ís X); ТАЕ 243" 
ж "FNCYs X) 

550 NEXT X 

S560 NEXT Y 

570 PRINT "4333 3 3 3 3€ € 3€ X 39€ 3€ 3€ 3€ 3€ 3€ 
XXX 3333€ (X! 

S80 FRINT 

$590 PRINT »» "AVERAGE REFRACTIVE 
INDICES" 

&OQ PRINT U33333 3433383333 HEHE 
хын 

610 PRINT "РЕТЕМ"» "REF. IND." 
620 FOF X=1 TO N-i 

630 PRINT FCX) ZCX) 

640 NEXT X 

650 PRINT 

&&O PRINT "33 39 9:9 3€ 3€ 3€ 3 EH € € € 
3C3t 39€ 9€ 3€ € 9€ 9€ 9€ 9€ 9€ "' 

670 GOTO 770 


6580 REM 

690 REM 33333939 9 ) 9 9 HEHEHE HEHE 
&9*5 КЕМ 

700 REM **CORRECT ERRORS SLUEx- 
710 PRINT 


720 PRINT “INPUT C IF CORRECT:0 
THERWISE":;"PREESZ NEWLINE" 

730 INFUT A$ 

740 CLS 

750 RETURN 


760 FEM 
жжЖЕМП SUBROLUTINE* 
Ж ЖҰ CC 


770 STOP 
720 REM #* END жж 


384 


Sample Printout: 


PRISM * ANGLE * MIN.DEV % RF.IN. 
& k k k k k k k k k k k k k k k k k Kk k k K k k K k k K k R k k Ro R K 


1 * 59.8 * 40.5 * 1,58 

1 * 60,1 * 40.2 Ж-1.,223 
2 “ 61.2 * 45.3 е T2327 
2 "2 ж 45.1 “71.562 
2 * 52.5 ы. 45.4 * 1.558 
k k k k k k k k k k k k k k k k k K k k k k k k k k k k k K k k k k K k 


AVERAGE REFRACTIVE INDICES 
k k k k k k k k k k k k k k k k k k k k k k k k k k k k k k k k k k k k 


PRISM REF. IND. 
I 1.54 
2 1.586 


* coe k k k k An n Je à An An ХХХХЕХЕХХХЖХХХХХхХЖҰХҰ« ХА xn x x x 


Comments: Note the importance of a check subroutine in this type of 
multiple-entry program. It gives the user the chance to verify that the 
input data is correct. It might have been better to have written a 
program to deal with any number of prisms and any number of 
readings. Consider what changes this would make to the program. 

There are many other physics experiments which may be treated in a 
similar way. For example: 


(1) The value of the gravitational constant 2. simple pendulum, 


; ; l , | | 
using the time period equation Т = 271 g for experiments with 


pendula of various lengths 1 to determine the average value of g 
resulting. 

(п) The determination of the velocity of sound, using a resonance 
tube to find the 1st and 2nd resonance lengths (L1 and L2 
respectively) and using the equation V = 2f(L2 – L1), where 
f = frequency of the sound, and V the velocity. 


4. “SERIES” 


Problem: We are asked to sum the series that gives us the value of e 
raised to the power x. This is: 
3 n 


. © Ж x i 
е шы жататы аа таты. ... for any value of x, with an accuracy 


n! 


of 1 part in 100,000 (i.e. 10-7, .00001). 


385 


Research the problem: This is the EXP function on your computer, 
evaluated as a series. The resulting value of, e.g., е, will be 
approximately the value of EXP 3 if you used it on the computer. ‘This 
Is a convergent series, E value of ie term gets smaller. For example, if 
we take x = 2, > от! Тел 1 = 2, whilst — 3 - Xi = 1.333... , At a certain 
point, the effect of adding the value of another term is to increase the 
sum by less than the accuracy we require. The summing is then 
finished. 

Procedure: This requires a procedure which allows any term in the 
series to be calculated from the previous term. This is the basic 
algorithm for summing many series. 

At this stage we need to consider if it is a specific problem or whether 
we could extend it to deal with other similar series-sum problems. It is 
important to make this decision before the program is written as it is 
often very time consuming to modify a program at a later stage. The 
answer is yes. We can then restate the problem as: a program is 
required which will sum a convergent series to any desired accuracy 
(subject to the limitations of the computer's arithmetic), provided that 
any term may be expressed as a function of the previous term, with the 
information needed being the first term and the common ratio. The 
common ratio is the equation that enables us to calculate any term 
from the previous one. 

For our problem: take the exponential series: 


x^ ҳ?-! 
S=] $K Peres PT 
2! (n – 1)! 
th 


n term 


In this series the first term is 1. 


h n-1 
The common ratio = X Ded The п" term is oD! and the 
п-2 п-1 25 | 
(n — 1)" term is — — The ratio is —— (асли = —— 
(n — 2)! (п- 1)! xn-2 п- 1 


We require an accuracy of one part in 100,000 (10-7). When the 
effect of adding another term increases the sum by less than this, the 
program should stop processing and output the result. 


Outline Procedure: 


1 Input necessary information 

2 Sum series term by term 

3 Compare sum with previous value 

4 Print out result when sums differ by less than required value 
Detailed Procedure: 

1 Input 1.1 Common Ratio – may be easiest to have a re- 


placeable line in program. 


386 


2 Sum 


3 Comparison 


4 Output 
Results 


Input 


N) н ка ка 


.2 First term - easily input 

3 Accuracy - easily input 

.4 Value of X - easily input 

.l Initialisation - set 1st term equal to given 


value which in turn is the sum of the series at 
this stage. 


2.2 Next term — may be calculated by multiplying 


first term by common ratio. 


2.3 Sum - may be calculated by adding this term 


to previous sum 


3.1 Compare this sum with previous value then 


EITHER go to 4.1 if the difference is /ess than 
that required or go back to 2.2 if difference is 
more than that required. 


4.1 Name of series 
4.2 Accuracy 

4.3 First term 

4.4 Valueof X 

4.5 Sum of series 

4.6 Number of terms 


Variables Table 


Name of Series 

Value of first term in series 

Value of X 

Accuracy required (difference between terms, such 
that program terminates when difference smaller 


than this). 


Processing and Output 


ii 

N 

51 

5 
51-5 


TsT*X/(N - 1) 


Value of current term being processed 

Number of terms 

Value of Sum of series of N - 1 terms. 

Value of Sum of series to N terms. 

Difference between the sums of the series to the Nth 
and (N - 1)" terms, checked against value of D. 
Calculates value of next term in series from current 
term. 


The common ratio is set in line 260. This line must be changed for 
different series. Spectrum users could use the DEF FN instruction in 
initialisation, and the FN instruction to evaluate the expression in line 
260. Try this when you have familiarised yourself with this function. 


387 


Flowchart “SERIES 


START 


NEWSUM = 
FIRST TERM 



















SUM = 
NEWSUM 





INCREMENT 
NO. OF 
TERMS 





CALCULATE 
NEXT TERM 
VALUE 






NEWSUM = 
NEWSUM PLU 
TERM 







PRINT 
RESULTS 


10 


ЕЕМ 


Program listing 
"SERIES" 


20 PRINT " ж» SERIES жж "s333" 
THIS PROGRAM SUMS ANY SERIES" 

ЗО PRINT ss"WHICH IS CONVERGEN 
T AND WHERE" 

40 PRINT з» "АМҮ TERM MAY ЕЕ CA 
LCULATED ҒЕОМ"› з» "THE PREVIOUS T 


ERM" 


50 PRINT »» "REPLACE LINE 260 ñ 
5 APPROFRIATE" 


60 PRINT ss "HIT A KEY TO START 
65 REM ##FAUSE О FOR SPECTRUM 
**IN LINE 70 жж 

70 PALISE 40000 

80 CLS 

90 PRINT “INPUT МАМЕ OF SERIES 
100 INPUT A$ 

110 PRINT “INPUT VALUE OF FIRST 
TERM" 

120 INPUT A 

130 PRINT “INPUT VALUE OF X" 
140 INPUT X 

150 PRINT “INPUT ACCURACY REQUI 
RED" 

160 INPUT D 

165 REM 

170 REM **«FIRST TERM** 

175 REM 

180 LET T=ñ 

185 REM 

190 REM **NUMBER OF TERMS 

195 REM 

200 LET N71 

205 REM 

210 REM s*SLUM S:NEW SUM S1* 
215 REM 

220 LET S128 

230 LET 5-51 

235 REM 

240 REM **xCALCULATE NEXT TERM*s 
245 REM 

250 LET N=N+i 

255 REM **SPECTRUM USERS САМ жж 

**#USE DEF FN HERE жж 

260 LET T=T*X/(N-1) 

265 FEM 

270 REM **CALCULATE NEW SLIM*#* 
275 REM 

280 LET $1=S1+T 

285 КЕМ 

290 REM **COMPARE S AND S1s* 
295 REM 


300 IF ABS (S1-S)>D THEN GOTO 2 


30 


310 


CLS 


315 REM **OUTPUT RESLILTS3* 


320 PRINT "SUM OF “;А%:" SERIES 


389 





230 PRINT "3333993 93 99 3 3€ € 96€ 
3t 3€ 3C 36 3€ 3€ аа ы 

340 PRINT "TO AN ACCURACY OF "; 
D 

350 PRINT 

360 PRINT "FIRST TERM=";A; ТАР 
Оз "VALUE OF X="; 

370 PRINT 

380 PRINT "SUM "513" МО. OF TE 
RMS "+N 

390 STOF 


400 REM **END PROGRAM*+* 


Sample printout: 


SUM OF EXPONENTIAL SERIES 

Yes e fe de k kok k k k kf kok koko КККК ККК Fe de He КККК КК 
TO AN ACCURACY OF .00001 

FIRST TERM=1 

VALUE OF X=1 

SUM 2.7182815 NO. OF TERMS 19 


Comment: Typical examples of other series that could be summed using 
the same program are given below: 





S=1+x+x°+x'+..... С... Po 
2 4 2n 
Cos x= 1-57 +7) TT (- "Quy for all x 
x? х? е yx2n+1 
Sin х=х- 9; t 5 sass Le) Tno Dj e sis 
Sel-xtx-x-4...... if x«1 


Now consider how you might improve upon this program. Ideally this 
should have been considered at the planning stage and not after coding. 
We should perhaps include a subroutine to correct the sum to the 
appropriate number of decimal places or routines to enable the user to 
check that input data is correct. We could LPRINT directly to the 
printer for our hard copy printout, to avoid using COPY. 


9. “GRAPH” 


Problem: 'To produce a useful hard-copy graph of various functions 
(Y 2 function X) in the positive quadrant (X and Y positive), with titles 
and scales included. 

Research the problem: The program must allow a variety of 
functions to be plotted. Thus there must be an input or a line of the 
program to be altered, according to the function which is to be plotted. 

Titles are to be printed, as are scale values. Hence we need to know 
the area of the screen in which we are to plot, and define the plotting 


390 


routine so that it keeps within this area. Indications of the scales should 
be visible on the plot screen, to enable approximate values to be read 
off. This will require inputs. 

Scale factors must be established so that the points to be plotted are 
within the defined area and good use is made of the available area, so 
that the graph is not cramped. The capacity to calculate the values of 
the dependent variable Y for a chosen range of X will be needed. 
Alterations of the values of X, so that the derived range of Y may be 
altered if necessary, should be possible within the program. 

As in all graphing programs, some degree of inspection and choice is 
required. In this case the requirement for scales to be printed requires 
the input of suitable intervals to make the graph functional. 

The program will hence require the following modules: 


1 Input and calculation of function to be plotted. Revision of X 
values and re-calculation if required. 

2 Input of X, Y scale values and calculation of scale factors. 
Printing of graph surround, titles, scale values. 

3 Plotting of function. 


Outline procedure: 


Module1: 1 Input: Function to be calculated. 
Values of X to define range of X 
required. 
2 Calculation: Calculate and store in array values of 
Y. 
Find maximum and minimum values 
of Y. 
Scale factor for X axis. 
3 Output: Maximum and minimum values of Y 
for specified range of X. 
4 Repeat 1 – 3 if required. User input to decide if required. 
Module 2: 1 Input: Low and High X, Y values. 
Scale values for X and Y axis divisions. 
X, Y axis titles. 
Graph titles. 


2 Calculate: Scale factor for Y. 

3 Output: Print titles, scale values, major scale 
intervals. 

Module3: 1 Input: Values of Y stored in array. 

2 Calculate: X, Y plot values, in accordance with 
scale factors. 

3 Output: Plot of function in specified area of 
screen. 


Detailed Procedure 


The descriptive algorithm (with user notes) for obtaining the best 
possible plot within defined scales is as follows. The user must be 
presented with the information required to make decisions as to 
suitable values for the X and Y axis scales. 


1 Define range of values of X for which values of Y are to be 
obtained. 

1.1 Input minimum value of X (MINX). 

1.2 Input maximum value of X (MX). 


Note: Values of X should be chosen such that the scale divisions 
correspond to values of X that will fit the defined purpose of the graph 
(range of X required). Thus the range of X would be chosen to suit the 
major scale divisions of the ‘graph paper’ drawn by the program. We 
would choose X to be plotted on a scale running from 0 to 5, to give 
scale divisions of: | 
0 1 2 3 4 5 
along the X axis, even though we were primarily interested in the plot 
of Y with X in the range, say, 0.5 to 3.9, adapting the X values to the 
constraints of the graph scales drawn on the screen. (See the sample 
printout for these.) Similarly, we might choose X axis scale values of 
0.4 0.5 0.6 0.7 0.8 0.9 

to fit within the constraints of the display, even when the prime сопсегп 
was the plot of Y when X runs from 0.5 to 7.9. 


1.3 The scale factor for X (DX) to be used in the calculation 
loop to derive values of Y is then (Number of points to be 
plotted оп X axis/(Maximum X - Minimum X)). DX = 
50 (МХ-МІМХ) for the ZX81 and 200 (МХ- MINX) 
for the Spectrum. 

2 Calculate values of Y for each value of X. 

2.1 Set X equal to minimum value of X (MINX). Start 
calculation loop. 

2.2 FOR each plot division on X axis (1 to 50 on ZX81, 1 to 200 
on Spectrum). 

2.3 Calculate Y = (Function of X). Use VAL to calculate value 
of function input as string. 

2.4 Store value in array N (N(F) = Y). 

2.5 Increment X for next plot point (X = X + DX). 

2.6 NEXT plot point on X axis. End of calculation loop. 


Note: The values of Y are now stored in array N. We now require to 
know the minimum and maximum values of Y that have been 
produced by the calculation. We must search the array N for these 
values. 


392 


3 Search Array for Maximum and Minimum values of Y. 

3.1 Set Maximum value and Minimum value variables 
(MAXY and MINY) equal to first Array element. 
(MINY = N(1),MAXY = N(1)). Start search loop. 

3.2 FOR each element in array (N(2) to N(End)). 

3.3 If array value is less than minimum value variable (М(Е)< 
MINY) then set minimum Y variable equal to array 
element (MINY = N(F)). 

3.4 If array value more than maximum value variable, set this 

variable equal to array element (MAXY = N(F)). 

.) NEXT array element. 

Inspect Range of Y. 

1 Print maximum, minimum Y values (МАХҮ,МІМҮ). 

2 Present menu choice of: (i) Recalculating for a different 
range of X. Program returns 
to 1.1 if selected. 

(11) Choosing Y axis values. 


Note: The user must now select the scale values for a range of Y such 
that all values of Y are within the range chosen and maximum vertical 
spread of plot points is achieved to avoid a cramped plot. This latter is 
the same decision as was made for the X axis values. A suitable scale 
must be chosen to conform with the scale divisions presented on the 
screen. The Y axis has three scale sections, requiring four scale values 
at the vertical divisions of the graph. 

If MINY were 0.12 and MAXY were 3.6 for a given range of X, for 
example, we might choose to set the minimum scale value for Y as 0, 
and the maximum as 4.5, allowing intermediate values of 1.5 and 3.0, 
which correspond to the scale divisions, so that the Y axis will be 
labelled: 


Qe oop 
C1 € Cn 


This gives the maximum vertical spread of plot points. 

Having made this decision, the user can input the maximum and 
minimum Y axis values. The decision can also be made to return to the 
start of the first module and re-define the values of X, choosing a 
different range (choosing to calculate for X = 1.5 to 7.5, for example, 
rather than the original choice of 0 to 6 for the range). This re- 
calculation can be done repeatedly until the best possible Y values for 
placing on the graph have been found, within the constraints of the 
ranges of X that are acceptable. 


Derive scale factor for Y axis. 


5 
5.1 Input minimum Y for scale (Y1). 
5.2 Input maximum Y for scale (Y2). 


393 


Note: These values are the same as will be inserted as scale values in 
string form for printing on the display. 


5.3 Scale value for Y plot is number of plot points on Y axis 
divided by maximum Y minus minimum Y. This is 
(DY = 30/(Y2 — Y1) for ZX81, 120/(Y2 — Y1) for Spectrum.) 


Note: Next module of program inputs scale values as strings and the 
strings for titles to be printed to the screen. 
6 Input scale values and titles. 
6.1 Input Minimum Y. 
6.2 FOR each remaining Y axis scale division (2 to 4). 
6.3 Input scale value to be printed. 
6.4 NEXT Y axis scale division. 
6.5 Print maximum and minimum X value (MINX and MX) 
as reminder of X axis values. 
6.6 FOR each X axis scale division (1 to 6). 
6.7 Input scale value to be printed. 
6.8 NEXT X axis division. 
6.9 Input Graph title, Function or subtitle, X axis and Y axis 
titles. 


This algorithm is coded in the program as the subroutine (lines 1000 to 
1680), called after initialisation of the arrays (lines 50 — 80). On return, 
all necessary data has been input or calculated. The main program 
prints the scale divisions on the ‘graph paper’ area of the screen, using 
two sets of nested loops (lines 130 — 230). Note the bypass condition in 
line 200 to prevent unwanted horizontal lines being printed. 

Scales and titles are then printed to the appropriate screen locations 
(lines 250 — 340). 

The plotting routine (lines 350 to 380) takes each value from the 
array N, finds the difference between this value and the defined 
minimum Y value (Y 1), and multiplies by the scale factor to get the Y 
axis plot position. Plot position is adjusted by the addition of constants 
to the X,Y values to be plotted, to place plot points within the graph 
paper area. These are: 

X axis: 10 on ZX81, 40 on Spectrum 
Y axis: 13 on ZX81, 52 on Spectrum 
The printout is obtained using COPY. 


Variables Table 


X$(6,4) Array to store X axis scale values (Input) 
Y$(4,5) Array to store Y axis scale values (Input) 
T$(4,25) Array for X, Y axis titles, graph titles (Input) 
N(50) Array to store calculated Y values 

E Loop variable 


394 


L Loop variable 


F$ Function input as string 

x Value of X 

MINX Minimum value of X (Input) 

MX Maximum value of X (Input) 

DX Step value for X value in calculation 

= Value of Y calculated. Each value stored in Array N(50) 


MAXY Maximum value of Y 
MINY Minimum value of Y 


M$ Menu choice (Input) 

Y1 Minimum value of Y axis scale (Input) 
Y? Maximum value of Y axis scale (Input) 
DY Scale factor for plot of Y values 


Flowchart ‘‘“GRAPH’’ 


Initialise 


col Calculate 
Scale 


factor for 
X 


Calculate 
Y values, 
Store in 





ағға 






Print 
Titles, 
Scales 






395 





396 





Restate Yes 


X value 


No 





Input Y 
Sco le 
Values 


Calculate 
scale 
factor for 
Y 


Return 


Spectrum modifications: 


The different plot screen of the Spectrum must be taken into account. 
This affects scale factors and the actual plot routine, and requires a 
larger array for the data (values of Y for the function of X). 

In the same area of the screen, where the ZX81 has 50 X axis plot 
points, the Spectrum has (4 x 50), 200. The array N must thus be 
initialised as N(200). The scale factors for Y and X also need to be 
calculated according to this changed plot resolution. Line changes 
needed are as follows: 

80 DIM N(200) 

360 FOR F=1 ТО 200 

370 РГОТЕ-40, (N(F) - Y1)*DY + 52 
1120 LET DX = 200/(MX - MINX) 
Delete lines 1135 and 1265 
1156 FOR F=1 TO 200 

1236 FOR F=2 TO 200 
1380 LET DY = 120/(Y2 - Y1) 
1390 Delete 30, Insert 120 
1520 Delete 30, Insert 200 





Spectrum users can also use the DEF FN and FN instructions to define 
the function to be plotted (in line 1050) and to evaluate the function 
within the calculation loop (line 1160). Revise the program to utilise 
these functions when they have been dealt with in Section W. 


Sample printout 


aS шаш ЖОЛ Ode c AUT ee ` 
+ + + + + 
+ + + & + + 
FUNEM * + + + 
3-0 +----+--- -—+——-- + 
+ + = + Ф e 
+ + + + + € 
RX IS + +u + + + e 
= = += E 
1:5  t---w4y"t----t----t----t----t 
+ F + + + + i 
+ ж + + + + < 
+ а” + + + £ £ 
тя + + + + ғ 
e meee pee KK tem KH tor Ф 
e 1.80 2.8 3.8 4.0 5.5 


GRAPH PLOT OF ESUaT Zor 
SIN x+x 


Program listing 


10 REM "GRAPH" 

20 REM *PRODUCES GRAPH OF 

30 REM *FUNCTION WITH TITLES 

40 REM жАМП SCALES FOR +VE 
*GUADRANT 


397 


330 


DIM Х%(6,4) 

DIM Y$(4,5) 

DIM T$(4,29) 

DIM N(S0) 

REM s*GOSUB INPUTS## 
GOSUB 1000 

CLS 

REM **PRINT PAPER ++ 


2 FOR Е=5 TO 30 STEP 5 


FOR L=0 TO 15 

PRINT АТ LiF} "+" 

NEXT L 

NEXT F 

FOR L=0 TO 15 STEP 5 

FOR F=6 TO 29 

IF Ғ/5- INT (Ғ/5) THEN NEXT 


J PRINT АТ L»F;"-" 


МЕХТ Ғ 

МЕХТ 1 

REM Ж%%ТІТІ ЕС жж 

FOR F=1 TO 6 

FRINT АТ 16s(F*5-1); X$ (F) 
NEXT F 

FOR F=1 TO 4 

PRINT АТ 20-F#3107Y$(F) 
NEXT F 

PRINT AT 1735: T$ (2) 
PRINT AT 1890] Реан 


PRINT АТ 19sS3TSC137 АТ 215 


8#T$(2)(1 TO 20) 


340 
TAE 
250 
260 
270 
250 
290 


1000 
1010 
Е" 

1020 


PRINT АТ 8»0:7%(42(1 TO 5); 
0:7%(42 (6 TO 10) 

REM **PLOT FROM ARRAY жж 
FOR Р=1 TO 50 

PLOT F*105s(NCFE2-Y10*DY413 
NEXT F 

GOTO 9999 


PRINT "GRAPH QF FUNCTION" 
PRINT »» “CALCULATION ROUTIN 


PRINT “INPUT FUNCTION TO BE 


. GRAPHED: IN": "FORM Y=FUNCTION X. 


1030 


PRINT “FUNCTION IS INPUT AS 


STRING. "s "ERROR MAY RESULT IN E 
*VALUATION",."OF SOME FUNCTIONS, І 
F THIS": “HAPPENS: REPLACE STRING 
INPUT","AND EVALUATION WITH INSE 

КТЕП", "PROGRAM LINES" 


1050 
1060 
1070 
1080 
1090 
1100 
1110 
1120 
1130 
1155 


1140 


INPUT F$ 

CLS 

РКІМТ ss "LOW VALUE OF X7" 
INPUT MINX 

PRINT з» "HIGH VALUE OF X?" 
INPLIT MX 

REM 3x*SCALE FACTOR X** 
LET DX=50/ (MX-MINX) 

REM **CALCULATE жж 

FAST 

LET X=MINX 


398 


1150 FOR F=1 TO 50 

1160 LET Y= VAL F$ 

1170 LET N(F2zY 

1180 LET X=X+¢1/DX) 

1190 NEXT F 

1200 REM **GET МАХЭМІМ Үжж 

1210 LET MAXY=N(1) 

1220 LET MINY=N(1) 

1230 FOR Ғ-2 TO 50 

1240 IF МСЕ) <МІМҮ THEN LET MINY= 
NCF? 

1250 IF MAXY<N(F) THEN LET MAXY= 
NCF) 

1260 NEXT F 

1265 SLOW 

1270 PRINT "MINIMUM VALUE FOR Y 
IS:" MINY 

1280 PRINT “MAXIMUM VALUE FOR Y 
IS:", MA XY 

1290 PRINT »» "CHOOSE SUITABLE VA 
LUES FOR Y “;"AXIS (Y) OR RESTAT 
E RANGE OF X ","(X)? INPUT X OR 
ү. " 

1300 INFUT M$ 

1310 CLS 

1320 IF МФ-"Х" THEN GOTO 1070 
1330 REM **SCALE FACTOR Ys* 

1340 PRINT “INPUT NUMERIC VALUE 
OF MIN. Y" | "( <= ":MINY: 'OFOR SCA 
1350 INFUT Yi 

1360 PRINT “INPUT NUMERIC VALUE 
OF MAX. Y".,"C >= ":MAXY: ' 0" 

1370 INFUT YZ 

1380 LET DY2s30/(Y2-Y1) 

1385 REM ** Y AXIS SCALES жж 
1390 PRINT "Y AXIS HAS 3 SCALE D 
IVISIONS, " “AND ЗО FLOT FOINTS." 
1400 PRINT “INPUT THE 4 SCALE VA 
LUES FOR Үн» "АХІ5. МАХ 5 CHF:S, " 
1410 PRINT “NEWLINE FOR BLANK. " 
1420 PRINT "MINIMUMC12»57?" 

1430 INPUT Y$(1) 

1440 FOR F=Z TO 4 

1450 PRINT "VALUE ";F;"?" 

1860 INFUT ҮФСЕ) 

1470 NEXT F 

1480 CLS 

1485 REM **X AXIS SCALES** 

1490 PRINT “INPUT X AXIS SCALES" 
1500 PRINT "LOW X IS " MINX 

1510 PRINT "HIGH X IS ":MX 

1520 FRINT з» "6 SCALE DIVISIONS: 
50 FLOT FOINTSON X AXIS." 

1530 PRINT "SCALE VALUES MAX.4 C 
HRS, "s "FIRST INPUT IS LOW VALUE. 
1540 FOR F=1 TO é 

1550 PRINT "SCALE VALUE ";F;"?" 
1560 INPUT X$(F) 

1570 NEXT F 

1580 REM **TITLES#* 

1590 CLS 


399 


1600 PRINT "INPUT GRAPH TITLE (М 
АХ 25 CHR)" 

1610 INPUT T$(1) 

1620 PRINT “INPUT FUNCTION OR SU 
ETITLEC2O","CHRS MAX)" 

1630 INPUT T$¢2) 

1640 PRINT “INPUT X AXIS TITLE ¢ 
20 CHRS MAX)" 

1650 INPUT T$(3) 

1660 PRINT “INPUT Y AXIS TITLE¢2 
ж5 CHRS) " 

1670 INPUT T$(4) 

1680 RETURN 


9990 REM 3*ENLD* 
9999 STOP 


6. “ELEMENT” 


Problem: To calculate for a chemical compound: (i) Percentage 
elemental composition and molecular weight or (1) molecular formula 
from inputs of, for (i), Number of atoms each element and for (ii) 
Percentages of each element. These are complementary calculations. 


Research Problem: We require a program that performs two separate 
operations. The common requirements will be the Element names, 
symbols and molecular weights. We choose to input and store these as 
data in arrays on the computer. This will require an input routine that 
is not used every time the program is run, and could be edited out. The 
elements involved should be capable of being changed to facilitate 
different analyses, and this must be allowed for in our program. This is 
an advantage over the alternatives of either defining all data with LET 
statements or the use of DATA and READ (which are only available 
on the Spectrum). 

The program must be split into two processing sections. The first of 
these (percentage elemental composition and molecular weight) 
requires an input for the number of atoms of each element. We can use 
a loop for this, using the loop variable to access the stored element 
names. Molecular weight equals the number of atoms of each 
compound multiplied by the atomic weight. This can be calculated 
within the input loop. Molecular formulae are then derived from the 
atomic symbol, plus the number of atoms, for each of the elements 
concerned. 

Percentage composition for each element is the number of atoms of 
the element, times the atomic weight of the element, divided by the 
molecular weight. 

The second section of the program requires an input loop for the 
percentage of each element. The proportion of atoms of each element 
will then be the percentage divided by atomic weight. This can be 
calculated within the input loop. To calculate the molecular formula, 
we require to know the minimum (to give us the smallest number of 


400 


atoms of any of the elements) elemental proportion. We can check this 
through another loop. The number of atoms of each element is then the 
proportion of each element divided by the smallest proportion. We 
could round this to integers, but will do so to two decimal places 
because the actual molecular formula may be a multiple of the derived 
formula. We should also indicate this possibility to the user. 

Zero inputs will be required when elements do not occur in the 
compound concerned. 

For a common organic analysis the following data will be stored via 
the input routine: 


HYDROGEN H 1.008 
CARBON C 12.01 
NITROGEN N 14.008 
OXYGEN O 16.00 
PHOSPHOROUS p 30.98 
SULPHUR 5 32.06 
CHLORINE CL 22,427 
BROMINE BR 79.916 


The data entry module is keyed in and the data input as above. The 
lines 15 to 160 could then be deleted if required, leaving the data stored 
in the arrays and available for access, as long as RUN is not used (or 
CLEAR). Spectrum users should replace line 3000 with: 3000 SAVE 
“ELEMENT” LINE 3010. The program is then SAVEd to tape by 
using GOTO 3000, when it stops at line 1990, or run again by keying 
in GOTO 200 as a command. 

You may like to derive an additional user dialogue to ask if the user 
wishes to SAVE or re-run the program, and according to the response, 
send control to the relevant line number. The procedure for the 
program is given below. 


Detailed Procedure: 


1 Data Entry Module 
1.1 Dimension arrays for data: Element Names, Element 
Symbols, Atomic Weights 
FOR each input (1 to 8) 
Input Name, Symbol, Atomic Weight 
GOTO subroutine to justify atomic weight (5 below) 
NEXT input 
Print user warning about the use of RUN 


ка кА ы ы қа 
O олњ OG N 


2 Menu 
2.1 Print Instructions and Menu 
2.2 If second calculation required, GOTO 4 


2.3 If first calculation required, proceed to 3 


401 


3 Percentage Element Calculation 


252 


3.2 


4.4 


Input: 

3.1.1 Reference for compound 

3.1.2 Initialise arrays, molecular weight variable 

3.1.3 ^ FOR each Element (1 to 8) 

3.1.4 Input number of atoms present 

3.1.5 Calculate total molecular weight (Molecular weight 
plus (number of atoms * atomic weight)) 

3.1.6 NEXT Element 

Processing/Output: 

3.2.1 Print Reference, Molecular Weight 

3.2.2 КОК each Element (1 to 8) 

3.2.3 Print Symbol, number of atoms 

3.2.4 NEXT Element 

3.2.5 КОК each Element (1 to 8) 

3.2.6 If no atoms present, GOTO 3.2.10 

3.2.7 | Calculate percentage as (Number of atoms times 
atomic weight) divided by molecular weight of 
compound, times 100 

3.2.8 | GOSUPB (5) for rounding and justification of results 

3.2.9 | Print Element symbol, percentage 

3.2.10 NEXT Element 

4 Molecular Formula Calculation 
Input 
4.1.1 Reference for compound 


4.2 


Initialise Arrays 

FOR each Element (1 to 8) 

Input percentage present 

Calculate proportion of Element as percentage 
present divided by atomic weight 


4.1.6 NEXT Element 

Processing/Output: 

4.2.1 Print reference 

4.2.2 Set C = 100 for percentage calculation 

4.2.3 FOR each Element (1 to 8) 

4.2.4 TH proportion is zero, GOTO 4.2.6 

4.2.5 If proportion less than current value of C, then let C 
equal proportion of element 

4.2.6 NEXT Element 

4.2.7 | FOR each Element (1 to 8) 

4.2.8 If proportion is zero, GOTO 4.2.12 

4.2.9 Number of atoms equals proportion divided by 
smallest proportion present, C 

4.2.10 | GOSUB (5) for rounding and justification to 2 d.p. 

4.2.11 Print Symbol, number of atoms 

6.2.12 NEAT Element 

4.2.13 Print user warning that multiples of this calculated 


formula may be the actual formula 


402 


5 Subroutine to Round and Justify 
(Input of number of decimal places (P) and number to be 
Justified (N) from data defined in main program modules) 


6 


1) 


2) 


1 X$ set to contain P zeros 

2 Integer value set as XN 

3 Decimal value set as XD 

4 Define X$ as rounded number string 


5.5 X$ returned to main modules for printing 
Auto-run. An automatic RUN routine using GOTO 200 is used to 
prevent the user entering RUN accidentally after LOADing 


Variables Table 


Input and main program sections: 


Holds element names 

Holds element symbol 

Holds atomic weight 

Loop variable in main program 

Loop variable in input routine 

Menu choice 

Reference for compound 

Molecular weight 

Holds input of number of atoms of element 
Holds input or calculated percentage of element 
Holds calculated number of atoms of element 
Constant for calculating percentages 


Round and justify subroutine: 


N 
X$ 
XN 
XD 
F 


Holds number for operation of subroutine 

Holds string form of number returned by subroutine 
Holds integer value of N 

Holds decimal value of N 

Loop variable in subroutine 


403 


Flowchart “ELEMENT” 


START 


DIMENSION 


DATA ARRAYS 





INPUT 
DATA 
INPUT 
CHOICE 
<> YES 
NO 


INPUT 





INPUT 





PERCENTAGE 





FIND 






LOWEST 


PERCENTAGE 













CALCULATE 





FOR EACH 
ELEMENT 








NUMBER 





NUMBER OF 





OF ATOMS 





ATOMS 








PRINT 






PRINT REF, 





SYMBOL, NO 





MOL.WT, 











OF ATOMS 






FORMULA 






CALCULATE 
PERCENTAGE 







PRINT 


INSTRUCTIONS 


STOP 






FOR EACH 
ELEMENT 







PRINT 





PERCENTAGE 


404 





FOR EACH 
ELEMENT 


FOR EACH 
ELEMENT 


Program Listing 


10 REM "ELEMENT" 

15 REM 33499) )9 3 9 9 9 9 9 3) (99€ 
1. DATA ENTRY. ROUTINE 
CAN BE DELETED WHEN 
ENTRY COMPLETE. 
325553555554 


20 DIM Е%с(8:310) 

30 DIM 5%(8»20 

40 DIM МСЕ) 

50 PRINT ~ ELEMENT SYMBOL 

MOL. WT. " 

55 PRINT 

60 FOR X=1 TO & 

ез REM ** ELEMENT МАМЕ жж 

70 INFUT Е%(Х) 

75 REM ** ELEMENT SYMBOL жж 

20 INFUT S$*$(X) 

85 REM ** ATOMIC WEIGHT жж 

90 INPUT MCX) 

75 REM *INITIALISE FOR GOSUBs* 

100 LET Рс 

110 LET N=M(X) 

120 GOSUB 2000 

130 PRINT X: TAB S;E$(X); TAB 1 

4;S$€$(X); TAB (27- LEN X$); ХФ 

140 PRINT 

150 NEXT X 

160 REM 
жн INES 15 TO 160 CAN BE 
DELETED AFTER DATA ENTRY 
AND REST OF FROGRAM ENTERED 
MUST USE #60TO 200% TO USE 
PROGRAM: NOT RUN: TO PRESERVE 
DATA. 


170 REM **END 1. жж 
ЭН 
180 REM 
200 REM 33933399 3 99 00€ EHH (90 
2, FROGRAM MENU ТП 
CHOOSE CALCULATION 
CEEE ETETE EEEE EEEE EEEE EE 


210 PRINT "CHOOSE CALCULATION Е 
EQUIRED: - " 

220 FRINT 

230 PRINT "TO INFUT NUMBER OF A 
TOMS AND GETPERCENTAGE ELEMENT С 
OMPOSITION AND MOLECULAR WEIGHT 
INPUT E" 

240 PRINT 

250 PRINT “TO INPUT PERCENTAGE 
ELEMENT ANA-LYSIS AND GET MOLECU 
LAR FORMULA INPUT M" 

260 INFUT A$ 

270 IF AS <> "E" AND AS <> "M" 
THEN GOTO 260 

280 CLS 

290 IF A$-"M" THEN GOTO 1000 


405 





295 КЕМ жж END 2, жж 
+++ Ж JE ЗЕ JOE 555552555555 


хх 3€ 3€ € 3€ 3€ 9€ 3€ 9€ € € 9E € EE CE 


З. PERCENT ELEMENT 
ЗЕ ЭЕ ЗЕ ЗЕ ЗЕ ЭЕ ЗЕ AE FE ЭЕ ЭЕ ЗЕ ЭЕ ЭЕ ЗЕ ЗЕ ЗЕ ЭЕ ЭЕ ЭЕ ЭЕ 55) 


300 PRINT "ENTER REFERENCE FOR 
THE COMPOUND" 

310 INFUT F$ 

320 REM жж INITIALISE жж 

230 DIM A(S) 

240 LET MOLWT=0 

200 DIM PCS) 

360 FOR Е=1 TO 3 

270 FRINT "NUMBER OF ATOMS OF " 
TESE) 7 "2" 

380 INPUT ACE) 

390 LET MOLWT=MOLWT+ CACE) *MCE2) 
400 NEXT E 

410 CLS 

420 REM **CALCULATE AND PRINT#* 

X*RESULTS жж 


430 PRINT "MOLECULAR WEIGHT AND 
COMF' QS IT LON ХА 9€ 9€ 3€ 3€ 3€ 96 9€ 
хын 

440 FRINT 

450 PRINT "ЕЕЕ: "ЕФ 

460 PRINT 

470 FEINT “MOL. WEIGHT= "s: MOLWT 
480 PRINT 

490 PRINT "MOL. FORMULA: "; 

S00 FOR E=1 TO 8 

510 IF А(Е221 THEN PRINT S$(E); 
ACE»; 

520 IF AtE?)z1 THEN РЕІМТ Z$(E»; 
wow NEXT Е 

240 PRINT “a "os 
220 FOR Есі TO 
260 IF АСЕ) =0 THEN GOTO 620 
565. REM *xCALCULATE FERCENTAGESZ* 


370 LET РХ(Ео-А(ЕзожМСЕО /MOLWT* 
100 

575 REM *INITIALISE FOR FOLIND2 
x3xSLEROLUTINE EE 

380 LET МЕСЕ) 

990 LET Pe2 

£00 GOSE 2000 

610 PRINT "FERCENT ";5%(Е); TAB 

(198- LEN ХФ) 7 X$ 

620 NEXT E 

&22 REM **xCOPFY HERE FOR FEINTED 
*hFEZULTZ xk 


230 GOTO 12500 


406 


640 REM жж END 3. жж 
355555555524 55553554 


é50 REM 

290 REM 3JX9 393339 Ж 33 3333333333 
4, MOLECULAR FORMULA 
HHH HAH HH HHH HHH HHH HEHE 


1000 PRINT “ENTER REFERENCE FOR 
COMPOUND" 

1010 INFUT F$ 

1020 REM **IIM ARRAYS+*+* 

1030 DIM ЕСЕ) 

1040 DIM NCE) 

1050 РЕІМТ 

1060 REM жжІМРІТ FERCENTAGES** 


1070 FOR E=1 ТО 8 

1080 PRINT "РЕРСЕМТ OF ";E$¿(E);" 
1090 INPLT PCE) 

1095 REM **CALCULATE FROPORTION® 


1100 LET N(E)=P(E)/M(E) 

1110 NEXT Е 

1120 CLS 

1120 REM **#CALCULATE AND PRINT** 
RESULTS жж 


1140 FEINT “*MOLECULAR FORMULA*" 

: ТАР OF "ххх € 39€ 3€ 9€ 3€ 9€ HE" 

1150 FRINT 

1160 PRINT "REF:";:R$ 

1170 PRINT 

1175 REM **CALCULATE MINIMUM 3s 
XxPROPORTION ELEMENT жж 


1180 LET C-100 

1190 FOR E-1 TO 8 

1200 IF МСЕ) =0 THEN GOTO 1220 
1210 IF N(E)<C THEN LET C=N(E) 
1220 NEXT E 

1222 REM **DERIVE FORMULA ** 


1230 FOR E=1 TO $Š 

1240 IF NCE)=0 THEN GOTO 1290 

1250 LET Р=2 

1260 LET NzN(ED/C 

1270 GOSUB 2000 

1280 PRINT S$(E); TAB 5- LEN X$; 

X$ 

1290 NEXT Е 

1295 REM жжЖСПРҮ HERE FOR PRINTED 
X*RESULTS жж 


1300 PRINT »s"MULTIPLES OF THIS 
FORMULA MAY", "BE THE ACTUAL FORM 
ША IF AT “s"“LEAST 2 ATOMS OF EA 
CH ELEMENT": "PRESENT" 


407 


"CASSFILE'' 


1320 REM 
** END 4. жж 
3C JC 3C HHH HHH 3E EXE ETE IEE HE 


1780 КЕМ 
1790 КЕМ 
X*ENDREUN INSTFELICTIGONZ33* 


1800 PRINT AT 20:07 "USE GOTO 200 
TO RUN AGAIN. "» "USE GOTO 2000 T 

О SAVE" 

15910 STOP 


1220 REM 
жжжж END PROGRAM *33* 
1530 КЕМ 


7000 FEM хх ххх А * 
5. SUBROUTINE TO ROUND 
AND JUSTIFY 
EMR 3C 26 Ae ut 3C HEH ЕЕ Жы 


2010 LET X$z"" 

2020 FOR Ғсі TO P 

2030 LET X$=X$+"0" 

2040 NEXT F 

2050 LET XN= INT М 

2060 LET XD= INT (10 ж F*(N-XN) 

+0, 5) 

2070 LET Х%- STR$ XN+". "+(X$(1 T 

Q P- LEN STE$ XD)+ 5ТЕ% XD+X%$)(1 
TO P3 

2080 RETURN 


2070 КЕМ ** END SLE ** 
+ + ЖЕ ЗЕ AE FEFE FE 3E ЗЕ ЗЕ ЭЕ PE ЭЕ FE ЭЕ ЭЕ ЭЕ ЭЕ ЗЕ ЭЕ 
О REM 
) REM 3999 3 9) 0 3 ж ЭЕ 3 3€ A Зє 
AUTO-RUN ROUTINE 
HHH HEHEHE 355555555555 


3000 SAVE "ELEMENT" 
3010 GOTO 200 


3020 REM #* END FROGRAM LIST жж 


Problem: То write a program which will store and manipulate the data 
concerned with cassette program listings and print out lists of these 
files. The data must be able to be updated. Cassette labels should be 
printed out, taking advantage of the fact that the Sinclair printer paper 


is the correct width for this. 


Research the problem: The program must have data entry and 
and storage for relevant data. This data must be displayed on screen 
and printed out if required. There must be a facility to add, delete and 
revise each portion of data separately. Data must be stored in string 
and numeric arrays, and there should be protection from accidental 


408 


clearing of the stored data by the use of RUN. However, since more 
data may be required to be stored than will fit in one set of arrays, there 
should be also a facility to clear the file data arrays deliberately, to 
allow a new file system to be set up. Any other variables must be 
defined by LET statements, and all variables re-initialised after 
CLEAR has been used. 

The best method of setting up a structure for this type of program is 
to have a menu presented to the user. From the menu, control can be 
passed to a separate module of the program which will perform the 
appropriate manipulations. After each set of operations have been 
performed, control will pass back to the menu module, which is the 
main program, looping back after each call (via а GOSUB or GOTO 
instruction) of the other program modules. 


Outline Procedure: 


Initialise storage arrays, variables, strings. 
Present menu options. 
Pass control to selected area of program. 
Required are program modules to: 
Input data (create a file) 
Print a file (screen and printer) 
Revise a file 
Delete a file 
Print cassette label 
Erase all files 
Control returns to (2) on completion of each operation. 
5 Adding a Save files procedure will enable an auto-run system to 
avoid the risk of using RUN, and wiping out data. 


H OF N н 


Detailed Procedure: 


1 Define the data to be held, its form, variables needed in the 
program, and strings to be used by one or more program sections 
to print titles for data. Initialise arrays, variables, strings. (See 
data table below.) This module is processed only once for each 
file system. 

2.1 Present Menu: 1 Create File 

2 View/Print File 

3 Revise File 

4 Delete File 

5 Print Cassette Label 

6 Save Files 

7 Erase all Files 

2.2 Loop back to start of Menu. If CLEAR has been used in 4.7, 


loop to (1). 


409 


4.1 


4.2 


4.3 


4.4 


4.5 


4.6 


Go to chosen program section. Use subroutines unless this causes 

problems. 

Create File. 

4.1.1 Define file number (existing files + 1) 

4.1.2 Input data 

4.1.3 Increment file count 

4.1.4 Sub-menu: View created file (GOSUB 4.2) 
Create another file (GOSUB 4.1) 
Menu (RETURN) 

4.1.5 Return to Menu 

View/Print File 

4.2.1 Get file number to view 

4.2.2 Print file contents on screen 

4.2.3 Sub-menu: Print file to printer (COPY) 
View next file (GOSUB 4.2) 
Menu (RETURN) 

4.2.4 Return to Menu 

Revise File 

4.3.1 Get file number to revise 

4.3.2 Print each item on screen 

4.3.3 Input new data if required, leave if correct 

4.3.4 Print new data if input 

4.3.5 Return to Menu 

Delete File 

4.4.1 Get file number to delete 

4.4.2 Print basic file data (name, reference) 

4.4.3 Confirm deletion 

4.4.4 Delete file contents 

4.4.5 Swap data from files of higher number to maintain file 

numbering as sequence 
4.4.6 Print new file numbers and basic data (reference and 
name) 

4.4.7 Sub-menu: Copy new file listing (COPY) 
Menu (RETURN) 

4.4.8 Return to Menu 

Print Cassette Label 

4.5.1 Get file number 

4.5.2 Print file contents on printer in suitable form 

4.5.3 Return to Menu 

Save Files 

4.6.1 Allow revision of program name (string) 

4.6.2 Allow return to menu if error 

4.6.3 Stop program until cassette ready 

4.6.4 Save ‘program name string’ 

4.6.5 GOTO Menu (prevent use of RUN) 


Note that this module cannot be a subroutine. Auto-run routines on 


410 


the ZX81 do not operate from within subroutines properly, so control 
must be passed with GOTO instructions. This procedure is modified 
for the Spectrum (see notes below). 


4.7 Delete all files 

4.7.1 Confirm deletion 

4.7.2 Use CLEAR to delete data 

4.7.3 Set marker for re-initialisation of variables on Return to 

Menu 

4.7.4 Return 

This cannot be a subroutine on the Spectrum (see notes below). 

The marker informs the main program loop that control must be 

passed to module (1) for re-initialisation. 
Each section of the program must then have the detailed procedures, 
including input checks, defined. Each area of the program can be 
treated as a program module for coding purposes. The sections must 
operate on the same data structures, so the first task is to define the 
arrays for the data, variables required, and strings for printing, so that 
a table of these may be used in developing each section of program. 


Data Table 

C$(10,4) Holds cassette reference (any four characters) 

N$(10,15) Holds cassette name (15 characters) 

P$(10,10,15) Holds for each cassette file 10 program names (15 
characters) 

T(10, 10,2) Holds for each program on each cassette tape 
counter readings (Start and Finish, numbers 
assumed to be in range 0- 999) 

F File number of Ше being manipulated іп 
processing 

IF Total number of files (up to 10) 

M$ String input from menus 

M Numeric input from menus 

S$ Current file program name 

N,L Used as loop control variables 

E$ Set as empty string for overprinting 

A$,B$,F$,G$ 

H$,1$,X$,Y$,Z$ Used as string literals for printing 

x Marker to show CLEAR has been used and hence 
that re-initialisation of variables and arrays is 
required. 


Another consideration is whether recursive or nested subroutines 
should be used. Care must be taken in the use of these facilities, and 
unnecessary complication should be avoided, since all control is passed 
back to the Menu, from which all modules can be accessed. However, 


411 


in the program recursion is used in the Create File routine to allow a 
sequence of data entries to be made (Line 1280), and (Line 2300) in the 
View File routine to allow stepping through the files. 

The View File routine is also available as a nested subroutine from 
the Create File routine to allow a newly created file to be viewed (Line 
2020). Apart from these instances a simple GOSUB - RETURN 
pattern of control has been followed, and the control flow in the Save 
Files routine has the same structure, but using GOTO instructions for 
the reason stated above. The different action of the CLEAR instruction 
on the Spectrum requires a GOTO instruction for the Erase All Files 
module (see below). 

Ten files are set up and manipulated in this program. Reference to 
the way variables are stored (Section T) will enable you to discover the 
memory required for this. The same section has the PEEK routine to 
discover program size. Work these out. You will find that the program 
could in fact store and manipulate up to 30 such files on the ZX81. 
Display file size will restrict the 16k Spectrum user to ten files, as in the 
program. 

The main program flow is illustrated in the first flowchart. The 
nested and recursive structures in the program are illustrated in the 
second, with the sub-menu control structures also shown. Sub-menus 
include a “Return to Main Menu” option. 


412 


Flowchart ‘‘CASSFILE’’ 


1. Main Program Flowchart 


START 






DIMENSION 
ARRAYS, 
INITIALISE 











6899 
SAVE FILES 
MODULE 







1909 
CREATE 


GOSUB FILES 


(M*1000) 






20909 
% VIEW/ 
PRINT FILES 





413 





CONTINUES SAVED 
PROGRAM ON 
LOADING 


REVISE 


GOTO MODULE 
ON SPECTRUM 


2. Recursion and Nesting the Create File and View File Subroutine 


MENU 










ENTER CREATE 





FILE NUMBER FILE SUB- 
=FILES+1 ROUTINE 
(LINE 1000) 
INPUT 
NEW FILE 
DATA 
INCREMENT 
NO. OF 
LINE 1230 
No RESPONSE “Ғ” 
= CREATE 


ANOTHER FILE 


INCREMENT 
FILE 
NUMBER 


GOSUB RECURSIVE 
1020 GOSUB 


114 






RESPONSE 
"V" = VIEW 
CREATED FILE 


GOSUB (A) FILE MODULE 
AS NESTED 
SUBROUTINE 


Yes 
z ү 


415 





INPUT 





START OF VIEW 









FILE FILE SUBROUTINE 
NUMBER (LINE 2000) 
ENTRY FROM 
CREATE FILE 
MODULE 
FILE Y 
EXISTS - 
2 
енуге -- VIEW 
ANOTHER FILE 
“M” = RETURN 


TO MENU 


LINES 2120 TO 
2185 






RETURN 
(TO LAST 
GOSUB CALL) 






YES 
COPY 


416 


“F” = VIEW NEXT 
FILE 


FILES = 
FILES + 1 


CHECKS IF FILE 
EXISTS 


RECURSIVE 
GOSUB 





Spectrum Modifications: 


1 Тһе Spectrum has a simplified auto-run procedure and printing 
the prompts is done automatically. Make the following line 
changes: 

9950 PRINT “PRESS A KEY FOR SAVE ROUTINE” 

9960 PAUSE 0 

9970 SAVE S$ LINE 9980 
This whole module (lines 6000 onwards) could be a subroutine on 
the Spectrum (unlike the ZX81, it will SAVE from a 
subroutine), but it should then be a self-contained subroutine, 


417 


without the jump at line 6100. The placing of the auto-run 
routine at the end of the program is done so that it is more visible 
to the user, since there is not a STOP or Program End. 
Replace SCROLL in lines 3090, 3150, 3170, 3230, 3250, 3265, 
3420 and 3495 by POKE 23692, - 1. 

The Spectrum wipes the GOSUB stack when CLEAR is used. 
This means it will not have a location stored to RETURN to. 
The Erase All Files module must therefore use GOTO 


statements: 
325 ЕМ =6 OR M =7 THEN GOTO M* 1000 


7090 GOTO 350 
Program Listing 


5 LET S="CASSFILE#1" 

10 REM "CASSFILE" 

20 DIM С%(1034) 

30 DIM М%(10:15) 

40 DIM Р%(10%10315) 

50 DIM ТС1і0» 10,2) 

60 LET X=0 

70 LET F=0 

80 LET E$z" 

YO LET A$z"CASSETTE FEF: ' 
100 LET B$-"CAZSETTE NAME" 
110 LET F$z"FILE NO, " 
120 LET G$="PROGRAM NAME" 
130 LET НФ-"ТАРЕ COUNT" 
140 LET I$="FROM ТО" 
150 LET TF=0 
140 LET X$= SS eee 


—— | 
170 LET ҮФ- U ea CFP 


120 LET 7%- "4 

I" 
190 REM Js 909 
171 REM **MENLI** 
192 РЕМ 33333 

200 PRINT 5% 

210 PRINT ТАЕ 103 "MENLI" 
220 PRINT 
220 FRINT "1. CREATE FILE" 

„240 PRINT »» “2. VIEW/FRINT FILE 
250 PRINT »»"3. REVISE FILE" 
260 PRINT з» "4. DELETE FILE" 
270 PRINT »» "5, PRINT CASSETTE 

LABEL" 

250 PRINT з» "4. SAVE FILES" 
290 PRINT з» "7. ERASE ALL FILES 

300 PRINT s> “INFUT YOUR CHOICE" 
310 INFUT M 
320 IF М<1 ОЕ М>7 THEN GOTO 300 
325 IF Mzé THEN GOTO 6000 
330 CLS 
340 GOSUB M*1000 


418 


350 CLS 
355 IF X=1 THEN GOTO 20 
360 GOTO 210 


290 REM KEKE t9 € € 9€ 9€ € € 9E 9€ € EE 
жж CREATE FILE SUE жж 
+++ 3C + 3E 9E 3E 3€ EXEC EE EXE E XE JE EXE XE 

1000 LET F=TF+1 

1010 IF F <= 10 THEN GOTO 1020 
1015 PRINT "««NO SPACE FOR АМОТН 
ER ҒЕПЕжж"») "ОМ RETURN TO MENU 
CHOOSE SAVE", "OPTION TO KEEF CUR 
RENT FILES"."THEN ERASE FILES AN 
D START NEW": "FILE ARRAY. " 

1016 FAUSE 300 

1017 RETURN 


1020 PRINT "READY TO CREATE FILE 
NO. "FF 

1030 PRINT АТ 2:0;7"INFUT CASSETT 
E REF. (4 CHRS MAX)" 

1040 INFUT СФСР) 

1050 PRINT АТ 2:0;E$; АТ 230: B$: 
"?(15 CHRS MAX)" 

1060 INPUT МФ СР) 

1070 PRINT АТ 230:Е%: АТ Z230:"IN 
PUT FROG. NAMES AND TAPE COUNTS" 
1080 PAUSE 300 

1090 FOR М=1 TO 10 

1100 PRINT АТ 4:0; "PROGRAM "FN 
1110 PRINT 6$;" ? (15 CHRS MAX)" 
1120 INPUT РФС(Ғ»МО 

1130 PRINT АТ 5з0:Е%; АТ 5% О0:Н%; 
" FROM ?" 

1140 INFUT TCFsNs1) 

1150 PRINT АТ 5,11;"ТО ? ы 
1160 INFUT TCF »Ns2) 

1170 PRINT АТ 530:Е%: AT 5» 0; "АМ 
OTHER FROGRAM ?(Ү/М2" 

1180 INFUT M$ 

1190 IF M$="N" THEN GOTO 1220 
1200 IF M$ <> "М" AND M$ <> "Y" 
THEN GOTO 1170 

1210 NEXT N 

1220 CLS 

1225 LET TF=TF+1 

1230 PRINT "CREATE ANOTHER FILE 
(F) VIEW" s “CREATED FILE (V) OR M 
ЕМ) (M)?" |+" INPUT F»V OR W " 

1240 INPUT M$ 

1250 IF M$ <> "F" THEN GOTO 1290 
1260 LET F=F+i 

1270 CLS 

1280 GOSUB 1020 

1290 CLS 

1225 IF M$-"V" THEN GOSUB 2020 
1300 RETURN 


1980 REM «эке кен 


1990 КЕМ жж VIEW FILE SUB ** + 
1991 REM HHH 0909090 (3 9 9 EERE 


2000 PRINT "WHICH FILE NUMBER?" 
2010 INPUT F 


419 


2015 REM **ENTRY FROM OTHER SUBS 


2020 CLS 

2030 IF TF <> 0 AND F <= TF AND 
F >= 1 THEN GOTO 2110 

2040 PRINT "NO FILE WITH THAT NL! 


2050 PRINT "MENU (M) ОЕ VIEW OTH 
ЕК FILE 7" 

2060 INFUT M$ 

2070 IF M$="V" THEN GOTO 2000 
2080 IF M$-"M" THEN RETURN 

2090 PRINT "FOLLOW INSTRUCTIONS 
PLEASE. " 

2100 GOTO 2050 


2110 CLS 

2120 PRINT FSF 

2130 PRINT A$ CSIF? 

2140 PRINT "Жж 3€ 3€ 3€ 9€ 9€ 9€ E 9€ 3€ 9€ 
JC 3C3€ 3€ 3€ 3€ 3€ 3E 9€ 9E 3E '" 

2150 FRINT G$; ТАЕ 20;H$? TAB 20 
; 1% 

2160 PRINT "-------------------- 
2170 ҒОЕ N=1 TÜ 10 

2180 PRINT Nr", "ЭРФС(ҒЭ М9? TAB 20 
ТЕМ 12; TAB 26: TCF» NS Z2 

2185 NEXT М 

2190 PRINT АТ 21:0: "ҒЕІМТСР 2» МЕХ 
T ЕПЕСҒ; OR MENLICM) " 

2200 INFUT M$ 

2210 PRINT AT Z1:0;E$ 

2220 IF M$z"P" THEN COPY 

2230 IF MS «> "Е" THEN GOTO 2510 
2240 LET Е=Е+1 

2250 IF F <= TF THEN GOTO 2200 
2290 DLS 

2260 PRINT "**NO FILE OF HIGHER 
NUMEEF3 * " 

2270 FALSE 150 

2280 CLS 

2290 GOTO 2210 


2200 GOSUE zozo 


2310 RETURN 


КЕМ 9333 33t3(t3€ 9€ 3€ EHH 
REM **xREVISE FILE SUB** 

795) REM ххх HHH HHH 3 

OO PRINT "WHICH FILE TQ REVISE 
1 Tu АҒ 

3010 INFLIT F 

2020 IF F <= TF THEN GOTO 3060 
3050 PRINT “NO SUCH FILE" 

3040 FALZE 120 

3080 RETURN 


fat А к F3 


3060 CLS 

3070 PRINT "FILE "Рӯ" DETAILS W 
ILL BE PRINTED. "ss" PRESS NEWLIN 

E IF CORRECT" » “INPUT NEW DETAILS 
IF REQUIRED. " 


420 


3080 PAUSE 150 

3090 SCROLL 

3100 PRINT AS; СФСР) 

3110 INPUT M$ 

3120 IF МФ-"" THEN GOTO 3170 
3130 LET C$CF)-zM$ 

3140 CLS 

3150 SCROLL 

3160 PRINT "NEM ":a$:C$(F?) 

3170 SCROLL 

3180 FRINT BS;" "МСР 

3190 INFUT M$ 

3200 IF M$-"" THEN GOTO 3265 
3210 LET N$(F)=M$ 

3220 CLS 

3230 SCROLL 

3240 PRINT A$ CCF? 

3250 SCROLL 

3260 FRINT "NEW CASS. NAME "МСЕ 
) 

3265 SCROLL 

3270 FOR N=1 TO 10 

3350 FRINT "FROG. "FN?" NAME ":P$ 
(Fs ND 

3370 INPUT M$ 

3400 IF M$ <> "" THEN LET ҒФСЕ» М 
)zM$ 

3410 PRINT AT 21:0; "PROG. "№" N 
AME ";PSCFsN) 

3420 SCROLL 

3430 PRINT AT 21,0; "ТАРЕ FROM: "; 
Т(Ғ» М» 12 

3440 INFLIT M$ 

3450 IF M$ <> "" THEN LET ТСР» № 
1)= VAL M$ 

3460 PRINT АТ 21%0: "ТАРЕ FROM: "; 
TCFsNo i337" TO: "ТЕУ N6 22 

3470 INFLIT M$ 

3480 IF M$ <> "" THEN LET ТСЕ» М, 
2)= VAL M$ 

3490 PRINT АТ 21,0; "TAFE FROM: "; 
T(FsN3512;" TO: "ТСЕ М2) 

3495 SCROLL 

3500 NEXT N 

3510 RETURN 

2990 REM 3J333 93333) 9 X 3X ы € 
4000 REM x*xxDELETE FILE SUB** 
4001 REM «ххх Хы CE 
4010 PRINT “WHICH FILE DO You WI 
SH TO".,."DELETE ? (1 TO 10)" 

4020 INPUT F 

4030 IF F <= TF AND F >= 1 THEN 
GOTO 4070 

4040 PRINT "x«NO FILE OF THAT NL! 
MBER»* " 

4050 FAUSE 150 

4060 GOTO 4430 


4070 FRINT F$;Fs АФ: C$ CF) 

4080 PRINT B$:" ":N$(F) 

4090 FRINT АТ 10:0;"INPFUT D TQ C 
ONFIRM DELETION"::3»"OR M FOR MEN 
LI, и 


421 


4100 INPUT M$ 

4110 IF M$ <> "D" THEN GOTO 4430 
4120 PRINT АТ 1430;"ALL FILES WI 
TH NUMBERS >"3Fs"WILL HAVE THEIR 
FILE NUMBERS", "REDUCED BY ONE, " 
4125 IF F=TF THEN GOTO 4220 

4130 FOR N-F TO TF-1 

4140 LET N$(N)=N$(N+1) 

4150 LET ССМ) C$ (N12 

4160 FOR L-1 TO 10 

4170 LET PS(NsLI=P$(N+15L) 

4180 LET T(NsL+1)=T(N+1s+sL+1) 
4190 LET T(NsL+2)=T(N+1+L $22 
4200 NEXT L 

4210 NEXT N 

4220 LET C$(CTFO-E$ 

4230 LET N$(TFO-E$ 

4240 FOR N=1 TO 10 

4250 LET P$¿(TF+N)=E$ 

4260 LET T(TF+N+1)=0O 

4270 LET ТТР» №2) =0 


4280 NEXT N 
4290 LET TF=TF-1 
4300 CLS 


4310 PRINT "FILE DELETED" 
4320 PRINT »% "МЕМ FILE LISTING: " 
4330 PRINT 

4340 FOR N=1 TO TF 

390 PRINT РФ №" “FASS ССМ) 
4360 NEXT N 

4370 FRINT AT 21:0; "COPY NEW LIS 
T (G), OR MENU СМ)" 

4380 INPUT M$ 

4390 IF M$ <> "C" THEN GOTO 4430 
4400 PRINT AT 2130;:E$ 

4410 COPY 

4420 CLS 

4430 RETURN 


4990 REM 333999 9 9 0 9 9 309€ 9€ ыы 
2000 REM 3x* PRINT LABEL SUEs3«* 
5010 REM 93sÓ3dmdUK3t3(93€((€ Y HEHE 
5020 PRINT "WHICH FILE DO YOU WA 
NT ТО РКІМТ"»% "А5 А CASSETTE LA 
BEL? 1 TU 19 3” 

5030 INF'LIT F 

5040 IF F >= 1 AND F <= TF THEN 
GOTO 5090 

5050 PRINT "#*NO FILE OF THAT МІ) 
MBER жж" 

5060 PAUSE 150 

5070 CLS 

5080 GOTO 5220 


5090 PRINT ›› "ЕЦЕ "ФЕ" WILL NO 

W BE PRINTED. “%%% "СНЕСЕ PRINTER: 

HIT А KEY TQ START" 

5100 IF INKEY$ ="" THEN GOTO 510 

© 

2120 LFRINT X$; "i"; A$:C$(F); TAB 
20rF$r:F; TAB Sir" F 

5130 LPRINT 2%: "| “2 БФ)! "3 МСР); 
TAE 212 


422 


5140 LPRINT 2%:Х%: "8 "0%; TAE ZO 

2% "УНФ: ТАЕ зір 

5150 LFRINT "I": TAB 20941") I$; 

TAB 31" B" 

5160 LPFINT X$ 

170 FOR М-1 TÜ é 

2180 LFRINT "Ё": №" ЗРФХРЭМО T 

AB 21:Т(ҒэМ1»: TAE ZS58:TCF»N$Z27 
TAB 31: "8"; Z$ 

510 NEXT N 

a400 LFRINT Y$; ХФ 

5210 LPRINT wee ТАЕ 20 

;F$:F; ТАЕ 31;"I" 

5220 LPRINT ҮЗІГІ "*5N$CF2; 
TAE 1? " [" 

3230 ІРЕІМТ Y$; X$ 
740 FOR N=7 TO 10 

5250 ІРЕІМТ "[";N:" "PCF No? Т 

АЕ 21: ТСҒ»Мз1»)) TAB 25% TCFs М2); 


_ AE 313" I":Z 
5260 NEXT N 
3270 LFRINT Y$ 
52280 RETURN 


5990 REM 33339 )9 99 9 9 4! 9 9 3 3 HEHEHE 
6000 REM ** SAVE FILES PROC жж 
6001 REM 3333 9999) HEHEHE ене 
6005 CLS 

6010 PRINT "SAVE FILES ON ТАРЕ Е 
OUTINE" 

Т PRINT ss "CURRENT PROGRAM МА 
ME Is" 

6030 FRI NT , 5 и пи и , 2$; "Ç "un "“ 
6040 PRINT эз"ІМРІТ А NEW NAME F 
OR THIS “s"“FROGRAM FILE OR PRESS 
NEWLINE":"ONLY TO SAVE WITH CUR 
RENT NAME. " 

6050 PRINT ss "INPUT M FOR MENU" 
6060 INFUT M$ 

6070 IF M$="M" THEN RETURN 

6080 IF M$=""" THEN GOTO 9900 
6090 LET 5%-М% 

6100 GOTO 9900 


6990 REM J3JQdUqcd(eogdndde 9) 99 9 9) 
7000 REM **DELETE ALL FILES SUE 
LE EEEE EEEE EEEE EEEE EEE EE] 

7010 PRINT "INPUT D TO CONFIRM A 

LL FILES" ARE TO BE. DELETED. ^ 

7020 PRINT ss “INPUT M TO RETURN 

ТО MENU. " 

7030 INPUT M$ 

7040 IF M$ <> "D" THEN GOTO 7080 

7050 CLEAR 

7060 PRINT ss “INPUT NEW NAME FOR 
THIS. FILE" 

7070 INFUT 5% 

7080 LET X=1 

7090 RETURN 


2890 REM 3 39 * X X X34 Ж Ж 


9900 REM жж AUTO-RLIN ROUTINE + 
2901 REM 3J3sd3J33393 33 ЭЕ ЭРЭР 9€ ЗРЗЕ ыж 


423 


Sample Printout: 


9910 CLS 

9920 PRINT “PROGRAM NAME IS " 
29°30 РЕ T NT и ии и - = $ 5 и ии "< 

9940 PRINT "#*NOTE IT DOWN3*" 
9950 PRINT :»"SET CASSETTE TO FE 
CORD АМО THEN" "PRESS A KEY TO 
SAVE. " 

9960 IF ІМКЕҮФ ="" THEN GOTO 9926 


9970 SAVE 5% 
9280 CLS 
9990 GOTO 200 


FILE NO.1 


CASSETTE REF: ЯРР1 
£ £ £ X x % X % X X X X £ £ X X £ X S 33 S a $ $ $ + 


PROGRAM NAME TAPE СОЫМТ 
FROM то 
1.GRAPHPLOT s 29 
2.RESIST з= exu 
3.STRINGSORT ес аза 
4. e a 
S. а ж 
б. & г. 
Ta ғ Pu 
в. e гы 
ә. e гы 
29. e e 


CASSETTE REF:RHPP1 FILE NO.i 
t CASSETTE NAME BRPPLICRHTIUONSÓ1 


PROGRAM NAME TREE COUMT 
FROM то 


GRAPHPLOT 
RESIST 


STRINGSORT 


CASSETTE REF:APP1 FILE MO. | 
CASSETTE NAME RPPLICRHTIGOPFSsi 





424 


Comments: 


This is a fairly long program. Work through the listing, checking you 
understand the operation of the algorithm within each program 
module. The individual manipulations of arrays and lists have all been 
encountered before, and each program module performs a different 
operation on the arrays and lists holding the data. The program is not 
by any means ‘idiot-proof’, although it is reasonably ‘user-friendly’ 
and you should note the various input checks used. The program can 
be crashed by inputs of bad (non-numeric) data into the numeric array 
holding the tape counter listings, and the main menu. Any file number 
request is checked. 

The input (string or numeric) from menus is checked, in different 
ways. Either another input is requested, or a default return to the main 
menu operates. Data correction is dealt with by the View File and 
Revise File modules. 

The program could be improved in two obvious ways. The first 
improvement would be a search routine to find and display the cassette 
file containing a desired program. A new module, 8 in the main menu 
and line 8000 onwards in the program listing, could be added to 
perform this operation. 

The second is that you cannot both print a file (in the View/Print 
File module) and then step through for the next file, since after printing 
the program automatically returns to the menu. Consider how you 
would modify the flow of control in lines 2190 to 2310 to allow this. 

Notice as a final point that data manipulation programs are long, not 
necessarily because of the processing manipulations themselves, but 
due to necessary input checks and user dialogue. 

The program can be easily revised for use with your audio cassette 
library, or other filing purposes. 


The program examples included in this Unit have been selected to 
illuminate the various structured programming techniques discussed in 
the rest of the book. In order to demonstrate the maximum number of 
these techniques being used in practice, it proved necessary to give the 
programs a strong scientific applications bias. Home users will 
doubtlessly be dismayed to discover that there is little in this part of the 
book which will be of practical use to them. However, it is important 
that they understand the principles behind the programs in this Unit, 
even if they do not actually key them in. 

As far as games and home applications programs are concerned, the 
Program Library at the end of the book (Appendix VI) should provide 
readers with enough examples to enable them to write their own 
programs tailor-made to their particular interests. 


V4: Games Programming 


Games are applications programs which are not of a type which fulfils a 


425 


specific purpose in a functional context; that is to say they are not 
written to do a specific scientific, educational or data-manipulation 
task. This does not mean that, as programming tasks, they are 
frivolous. The enjoyment of playing the game on or with the computer 
is the application for which the program is written, but the task of 
programming a game is often difficult. Games programming is good 
practice for finding, deriving and coding algorithms and producing 
efficient and user-friendly programs. Graphics manipulation plays a 
larger part in games programming than in most applications programs, 
and such programs are also more interactive, requiring repeated inputs 
and outputs. 

BASIC, an interpreted language, is often slow for games purposes. 
Fast action graphics games (SPACE INVADERS and their spawn), 
are written in machine code for speed of operation, as are tactical 
games where exhaustive exploration of possible moves is required (such 
as chess). Effective games can be programmed in BASIC, however, if 
the amount of calculation is not too great. 

An area of interaction between Games and Application 
programming is the question of simulation. A program, given data and 
rules for manipulating the data, simulates a situation. In a serious 
application, this would be a real situation, with the manipulations 
performed as known or hypothesised relations from scientific 
knowledge. A game simulation would use invented relationships, or 
perhaps simplified formulae, if it dealt with a ‘real’ situation. The 
techniques would be essentially the same, and are used in a program in 
the same fashion. From the point of view of this book, games may be 
considered as programming exercises. All the techniques you have 
learnt can be put to use in writing games programs. 


V5: Example Programs 


The first program we will examine 15 a classic computer simulation, or 
rather implementation, of Life. This is not really a game, but a process 
that the user sets into operation, and observes. Invented by John 
Conway, the game simulates a colony of cells, which grows from the 
initial colony according to three simple rules. Cells are placed on a 
grid, and in each generation the succeeding generation is determined 
by the number of neighbouring grid squares which contain a cell. The 
rules are these: 


1 Ifa cell possesses, іп the 8 adjacent grid squares, either two or 
three neighbour cells, it survives into the next generation. 

2 А сей dies (is removed from the grid for the next generation) if it 
has (1) 4 or more neighbouring cells (overpopulation) or (11) 0 or 
1 neighbours (isolation). 

3 Each grid square which is empty, but has exactly three 
neighbours is a birth cell, and a cell will appear in this position in 
the next generation. 


426 


To implement this on the computer, 
manipulation will be involved since a grid is a 2-D array. It is also 
necessary to have more than one such array, since the grid of 
Generation (n + 1) is defined from the grid of Generation (n), and none 
of the cells of Generation (n) can be altered until the checking process is 


complete. 


The array of Generation (n) must have each grid position checked, 
and the number of neighbours counted. In accordance with the rules, 
the future of the cell at that position is determined and, if empty, 
whether a cell will be born. This data is stored in one array, and then 
the other array is updated to take account of the changes. Spectrum 


users should delete lines 220 and 390. 


Program Listing 


S REM "LIFE" 
10 PRINT TAB i1z:"*LIFE«" 
20 FRINT 
20 DIM 85(16%162 
40 DIM Bcté.1ié) 
50 DIM Ас, 2) 
80 LET GEN=0 
70 REM #ENTES START COLONY+* 
SO PRINT "ENTER START COLONY"; 
"ON A Xé GRID"ssse"INFUT 6 STRI 
NGS OF SPACES AND "."AZTERISKZ ¢ 
жу" 
70 PRINT 
100 FOR F=1 TO ё 
110 PRINT "STRING ";F; 
120 INFUT A$CF) 
130 PRINT " “SASCF) 
140 NEXT F 
145 REM xFLACE COLONY IN ARRAY* 
150 FOR F=1 TO é 
140 FOR Z=1 TO ë 
170 IF A$(FyZ)="*" THEN LET ЕСЕ 
+9, 1+5) =1 
120 МЕХТ 2 
170 NEXT F 
200 GOSUB 1000 
205 REM *INCREMENT GENERATIONS 
210 LET GEN=GEN+1 
220 FAST 
230 FOR Х=2 TÜ 15 
240 FOR Үс2 TO 15 
250 REM *SET COUNTER* 
260 LET C=0 
265 REM *CHECK NEIGHBOUR CELLS 
270 IF А(Х-1:Ү) =1 THEN LET C=C+ 
1 
280 IF ACX-isY-1)=1 THEN LET C= 
С+1 
290 IF АсХ-15Ү+1)=1 THEN LET C= 
C+1 
300 IF A(X:Y+1)=1 THEN LET C=C+ 
1 
310 IF ACXsY-13=1 THEN LET C=C+ 
1 


427 


it is obvious that array 


320 IF ACX4+1;Y-1)=1 THEN LET C= 
+1 

330 IF ACcX41»Y2021 THEN LET C=C+ 
1 

340 IF ñ(X+1yY+1)=1 THEN LET C= 
[^41 

34& REM xDECIDE IF BIRTHx 

350 IF ACX:Y220 AND Cz3 THEN LE 
T BCX*Y2z1 

255 REM *#DECIDE IF DEATH* 

360 IF А(553Ү9гті AND (Crt OR С<2 
) THEN LET ECX:Y)=0 

370 NEXT Y 

3S0 NEXT X 

390 SLOW 

400 GOTO 200 


1000 CLS 

1002 PRINT АТ 931: "GENERATION "; 
GEN 

1010 FOR X=1 TO 16 

1020 FOR Y=1 TO 16 

1025 REM ЖИРПАТЕ ARRAY Аж 

1030 LET ACX» YOzBCX YO 

1035 REM *PFINT ARRAY* 

1040 IF ACX:Y)=1 THEN PRINT AT X 
+Z 153 OH” 

1050 IF А(ХзҮз-0 THEN FRINT AT X 
T2iY46:" " 

1060 NEXT Y 

1070 NEXT X 

1080 COPY 

1090 RETIREN 


428 


Flowchart of “LIFE? 


START 


INITIALISE 
ARRAYS, 
GENERATION 


PRINT 
INSTRUCTIONS 












PRINT 
STRING 
NUMBER 






PLACE IN 
ARRAY B 





429 


INCREMENT 


GENERATION 















COUNTER C 
= No. of 
NEIGHBOURS 
FOR A(X,Y) 






A(X,Y) 
(OCCUPIED 


NO 





=1 


B(X,Y) =1 
(BIRTH) 


430 


Flowchart of ‘ІЕЕ’ - Subroutine 1000 


ENTRY 


PRINT 
GENERATION 





COPY 
SCREEN 
RETURN 


431 


PROGRAM STRUCTURE 


The program breaks down into the following sections. 


(1) Initialisation (lines 30 — 60). Two 2-D arrays, 16 x 16 are set up, 
with a 6 string array to hold the start colony. The generation 
counter is set as 0. 

(üu) Input of start colony (lines 70 — 140). 6 strings of 6 characters are 
entered and printed out. 

(iui) Start colony is placed in array. The lines 150 — 190 place 1 
(representing a cell) in array B when an asterisk is present in the 
string array entered in (11), in the central 6 x 6 block. 

(iv) Print Subroutine. Line 200 sends control to the subroutine. This 
uses a double loop to set array A as array B, then prints asterisks 
on the grid for each 1 found in array A. Note that at the end of 
this subroutine arrays À and B hold the same data. The screen is 
copied, and control returned to line 210. 

(v) Checking of population to determine next generation. The 
generation is incremented and the computer put into FAST 
mode. The double loop is set up, and each cell in array A is 
checked in turn for the number of neighbours it possesses. The 
counter C is incremented by 1 for each neighbour. Line 350 
places a ‘born’ cell into array B if the cell in array A is blank, 
and the number of neighbours is three. Line 360 kills any cell 
with more than 3 or less than two neighbours. The 
corresponding array B element is set to 0. At this point array B 
holds the revised population for the next generation. Array À 
must be left alone during the check procedure. This is the reason 
why the two arrays are made equivalent in (iv) above. 

(vi) Control is returned to line 200, and steps (iv) and (v) repeated. 


The pattern of asterisks input initially determines how the population 
develops. Some patterns die out, after a number of generations, some 
enter a stable sequence that repeats, and there is a general tendency 
towards symmetry if a population survives long enough. 


The next game is also an implementation of a favourite game for 
computers, which has existed since the days of printout-only terminals 
(which is where the instruction PRINT in BASIC comes from, as a 
hangover from hard-copy terminals transferred to implementation on a 
screen). The basic idea, upon which many variations have been 
created, is that a landing must be made on the lunar surface at a speed 
low enough to prevent a crash. Rockets can be fired to slow the craft, 
but the fuel supply is finite. If the fuel supply is exhausted, a crash is 
inevitable. The game was originally played with a printout of the data 


432 


only. This version uses one side of the screen for a graphic display, and 
prints the data on the other. Spectrum users must replace line 40 with 


40 PAUSE 0. 


2 REM "LANDER" 

10 PRINT TAE 10; *LANDER*";: AT 
4,0; "LUNAR LANDING GAME. YOU ARE 
"S"INITIALLY 500 METRES ABOVE T 

HE", "SURFACE OF THE MOON. YOLI НАМ 
E “5 "100 "FUEL UNTTS " 
ZO PRINT "FRESS Е TO FIRE ROCK 
ETS TO SLOW DESCENT. EVERY FIRING 
USES 5 FUEL UNITS. YOU MUST LAND 
SLOWER THAN z TO SURVIVE. GOOD L. 
ШЕ, " 
30 РЕІМТ з» "FRESS A KEY TO STA 
КІ” 


40 FALSE 40000 

45 REM ** I NITIALISEx* 

SO CLS 

&O PRINT АТ 20315) "deka 
ulis " 

70 LET Fz100 

mO LET Н==00 

90 LET 5-15 

72 REM **xzTAOàRT OF ІППРжж 

100 LET V=0 

110 IF Hz&OO THEN РЕІМТ АТ 20-Н 
/30320;" " 

120 PRINT AT 105 “FUEL: “РЕТ "а" 
: TAB O:"HEIGHT:":H;" "? TAB O;" 
SPEED; "3355" " 

135 REM *#*#CHECK ROCKETS жж 

140 IF INKEY$ ="F" AND F >= 5 T 
HEN LET V=Š 

150 IF V THEN PRINT AT Zi-H/30: 
203" Vy" 

160 IF F<5 THEN PRINT АТ 1з7: "% 
EMPTY +" 


170 LET FeF=y 

180 LET S=S+2-V 

190 PRINT АТ 20-H/30; 20; " ii 
TAB 20; " 4 

192 КЕМ жж СНЕСЕ IF LANDED жж 
200 IF H<30 THEN SOTO 230 

210 LET HzH-Z 

220 GOTO 100 


225 REM ** LANDING RESULT жж 
230 IF 5<4 THEN PRINT АТ 21,10; 
"PERFECT LANDING" 

240 IF 545 AND 524 THEN PRINT А 
Т 21310: "BUMPY BUT SAFE" 

220 IF © >- & THEN PRINT АТ 21, 
10: "CRASHED AND SMASHED" 

260 PRINT АТ 1230: "ANOTHER GAME 
?СІМРИТ Y OR ND" 

270 INFUT AS 


433 


ЕО IF A$z"Y" THEN GOTO 20 
то REM *END* 


2 
2 
4-- 
в. 


Lines 10 to 30 print instructions, and line 40 stops the program until а 
key is pressed. Lines 50 to 90 clear the screen, print the “lunar surface' 
and set the variables: F is fuel units, H is height above surface, S is 
speed of descent. 

The main program is in the loop between lines 100 and 220. V is set 
to zero as a flag, and the craft is printed by line 110 if the scale set 
allows it to be on screen. The craft disappears off the top of the screen if 
the height is greater than 600 since the PRINT AT instruction scales so 
that 1 print line = 30 metres of height. Line 120 prints the current data. 
Note the spaces after the variables to overprint if the values decrease, 
or in the case of the speed becoming positive after being negative. 
(Negative descent speed means ascent.) 


Line 140 checks if the R (for rockets) key is being pressed. If it is, V 
Is set to 5. Line 150 prints rocket exhausts below the craft if the R key 
was pressed (evaluated by V = 0 = False if not pressed, V = 5 = True if 
pressed). The fuel is checked (line 160) and reduced by the value of V if 
not empty. The speed is adjusted by increasing it, then reducing it by 
the value of V if the rockets have been fired. Line 190 overprints the 
craft and rockets, and 200 checks if the surface is near enough for 
landing to be assumed. If it is, control is transferred to the landing 
message section. If not, the height is adjusted and the program loops 
back to repeat the process. 

Notice that the variable V is used in three ways within the loop, and 
that the loop structure, using INKEYS to see if the player has input 
instructions, is common in interactive games. It provides a simulation 
of a real-time process. In this game, the speed is assumed to be metres 
per second (hence the simple LET H = H - S of line 210). It is actually 
nominal ‘metres’ per program loop! Other games can wait for inputs, 
but the use of a loop allows the inexorable attraction of gravity to go on 
its way unless the player does something. Spectrum users, with their 
faster computing, may wish to insert a PAUSE instruction in the loop. 

Programming for this type of game can show the programmer that 
certain structures of programs are inefficient in program execution, 
since conditional branches to routines requiring calculation will 
noticeably slow the loop. In the interests of a good game, structured 
programming practice may be set aside and speed of execution can 
become a goal in itself. However, remember not to transfer these 
techniques to serious programs! 

Games programming can become extremely complex when we 
consider the strategy and tactics which must be built into the response 
from the computer. We have dealt with only the simplest form of game, 
and have not included any of this type of game. We suggest that you 


434 


put to work the techniques we have shown you in this text to analyse 
some of the tactical games in the popular computing magazines, if this 
area Interests you. In order to start learning to appreciate the problems 
involved, you could start by writing a program to play Noughts and 
Crosses. You may think this is a very simple game, but it is a 
surprisingly difficult one to program! 


435 





E 
o 
f 


СОЖ быш 


— 


2 


s 


PART FIVE 


COVERING THE WHOLE 
SPECTRUM 





чон YET wig) 
4° SYM 


SECTION W: THE SPECTRUM 
W1: The Spectrum System and Keyboard 


This Unit introduces the Spectrum microcomputer system. As a 
Spectrum user you have been referred to this Unit because, whilst the 
BASIC language that both the Spectrum and ZX81 use (Sinclair single 
keystroke BASIC) has only minor differences between the two 
machines (although the Spectrum has additional features that the 
ZX81 does not possess, such as colour, high-resolution graphics and 
sound), there are greater differences in the arrangements of the 
keyboard. The Spectrum system is also simpler to set up and connect. 

After reading this Unit, you should return to the start of Section C 
(page 19) to start using the BASIC language, once the keyboard and 
the way to access all the confusing array of characters grouped on and 
around each key have been explained. Sections A and B are for the 
ZX81 only, but you will find in this Unit the same information as it 
applies to the Spectrum. The main text takes you through the Sinclair 
BASIC language, using the same instructions for the ZX81 and 
Spectrum, any minor differences being noted. This involves the 
introduction of a few of the Spectrum’s enhanced BASIC instructions, 
but most of the additional facilities of the Spectrum are covered in the 
next Units, to be read after you have worked through the main text and 
have learnt the BASIC programming techniques. 


SPECTRUM SYSTEM DESCRIPTION 


We assume that you have in front of you the components of your 
Spectrum system. 
This consists of: 


1 The ZX Spectrum microcomputer. 

2 Either 16k of internal RAM or 48k (although nothing in this 
book demands more memory than 16k). 

3 The ZX power supply, with the correct plug attached for the a.c. 
power sockets you have. 

4 The ZX printer and its socket. 

5 A domestic TV to act as a display monitor. 

6 A mono cassette recorder, with an a.c. supply lead (if not battery 
powered). 

7 The aerial/antenna cable which connects the Spectrum to your 
TV set. (In the U.S. this is via a switch box.) 

8 A pair of cassette recorder leads, fitted with 3.5mm jack-plugs at 
either end. 


These components make up a complete system, the least crucial part of 
which is the ZX printer. If you do not have a printer then you can 
ignore the printer-related sections of this book and learn BASIC 


439 


programming techniques just as well. It is extremely useful, however, 
to have a printer both for hard-copy printouts of results and, more 
importantly, for program listings for documentation purposes. 

The cassette recorder should preferably be mono, since stereo tape 
deck recording heads can cause problems, even used on only one 
channel. The cheaper recorders work somewhat better (due to the less 
sophisticated audio circuits being better for handling the crude form of 
the computer’s signals) than more expensive ones, but get one with a 
tape counter, as finding programs without one can be an irritatingly 
time-consuming process. 


FIGURE 3 


SPECTRUM SYSTEM DIAGRAM 


a.c. household power supply 






TV AERIAL 
CONNECTION 


POWER 
SUPPLY 


TELEVISION 





9V d.c. 


кезі 


PRINTER 





CASSETTE // 
RECORDER Ж 


U.S. Users тау have antennae on/off switch 
fitted in aerial lead, shown as dotted box in diagram. 


440 


FUNCTION OF COMPONENTS 


Here is a brief rundown of the function of each of the components of 
the Spectrum microcomputer system. 


Device 
Spectrum computer board 


Keyboard 


TV Set 


Cassette recorder 


Printer 


Power Supply 


Cables 


Function 


Data processing and control of inform- 
ation handling. 

Input from keyboard or cassette. Output 
to ТУ screen and printer. Also holds the 
16k or 48k of RAM memory. K stands 
for kilobyte. One byte is eight bits, which 
are the binary digits (0 and 1, represented 
by on-off switches in the computer) 
computers work with. A kilobyte is 
roughly 1000 bytes, hence the name. (It 
is actually 2^, 1024). 

Input of information. Programs, data 
and commands are keyed in. 

On-line control. 

Used as V.D.U. (visual display unit) 
monitor. Provides on-line output of 
information - visual display of programs, 
results (data, graphs, pictures) and 
control commands. 

Off-line storage of information Program 
data are stored (written) as coded 
electromagnetic impulses on cassette 
tapes. They can be played back (loaded) 
at any time for use again. The computer 
reads the data from the tape. The 
Spectrum will also be able to use the 
microdrive, storing the coded impulses 
on a magnetic-coated disc, when it 
becomes available. 

Output device, to provide a permanent 
printed record of the screen display, 
program listings or information in the 
computer memory. Prints on electro- 
sensitive paper. 

Supplies the d.c. current (9 volts at 1.2 
amps) to run the computer, RAM pack 
and printer, from the household power 
supply. 

To interconnect the devices which make 
up the system. 


The printed circuit board inside the Spectrum holds and connects the 


441 


IC (integrated circuit) microchips which provide the computing 
facilities. These are: 


1 


4 


Z80A CPU (Central Processing Unit) microprocessor chip 
which is the heart of the system. It is used in many other 
microcomputers, and performs the arithmetic manipulations. 
ROM (Read Only Memory) chip holds the 16k BASIC 
interpreter which translates BASIC instructions into the 
machine-code instructions that the 780А operates with. The 
data in this chip is fixed, hence the name, and also stable - it 
remains when the power is switched off. 

RAM (Random Access Memory) chips provide the memory 
store. This is either 16k or 48k, depending on which version of 
the Spectrum is owned. This memory is volatile — the data is 
stored as electrical impulses and is lost when the power is 
switched off. This memory stores the BASIC program, the 
values of variables (including some system variables that the 
computer uses for to organise its own affairs), a memory picture 
of the ТУ screen display, and the stacks which hold the numbers 
whilst they are being manipulated. The memory organisation is 
described in Section U. 

The Logic Chip co-ordinates the operation of the other chips. 


Also mounted on the board are the stabiliser for the 5 volt supply the 
computer takes from the power-supply socket, the colour TV signal 
encoder and modulator circuits and the sockets for the connecting 
cables to the ТУ and cassette recorder. There is also a small speaker for 
the sound output. 


CONNECTING UP 


1 


2 


Set aside an area to work in and set up your television, 
Spectrum, cassette recorder, printer (if you have one) and the 
Spectrum’s power supply, as shown in the diagram of the system 
(Fig. 3). 

Always remember to connect the printer to the back of the 
Spectrum before you switch the power on for the ZX power 
supply. With the printer connected, the TV aerial lead 
connected to the ТУ socket on the Spectrum, and the ‘EAR’ 
and ‘MIC’ leads correctly set up as below, you can then plug into 
and switch on the a.c. power (household) supply. 

Connect the printer into the socket at the rear of the 
Spectrum. Make sure the gap in the board at the rear of the 
Spectrum connects with the plastic piece in the printer socket, 
then push firmly home. 

Connect one end of the twin cassette leads into the EAR and 
MIC sockets of the cassette recorder. Push firmly home and 
twist slightly to get good connections. Take the same colour plug 


442 


as is in the EAR socket of the cassette recorder and place it in the 
Spectrum EAR socket. Place the other in the MIC socket. 
Inset the Jack-plug leading from the power supply into the 
socket marked 9 V d.c. on the back of the Spectrum. Connect 
the TV aerial/antenna lead to the aerial socket of the TV. 
Your system is now set up. Check the ТУ is turned off, and no 
cassette keys are depressed. Plug the ZX power supply and 
cassette leads into the a.c. (household) power supply sockets, 
and switch them on if they have switches. 
3 Switch on the TV. Choose a channel with the push button or 
other channel select control, and tune the TV until the display: 


(O 1982 Sinclair Research Ltd 


appears on the screen. Adjust the tuning until the display is 
clear, and the brightness, contrast and colour (if you're using a 
colour TV!) controls to get a good picture without it being too 
bright (since you are going to spend some time looking at it from 
close up). 

Note for U.S. users: In the U.S., the antenna lead connects 
with standard terminals to the TV. An antenna on/off switch is 
provided between the computer and the TV. The computer has 
a channel select switch to select channel 2 or 3. Whichever 
channel is not transmitting should be selected, and the TV 
tuned until the computer display is obtained. 

4 Press a few keys to get some characters printed on the 
screen — these should appear at the bottom of the screen. Then 
press the CAPS SHIFT and 1 (EDIT) keys together, to clear the 
screen. 

5 Press the Z key. The screen will print COPY at the bottom. 
Then press ENTER. The printer will start operating, feeding 
paper through. There will be nothing printed on it because there 
is nothing printed on the screen. Check that the printer paper 
does not rub against the side of the printer as it is fed through. If 
it rubs, pull it gently away from the side as the paper is fed 
through. 

You now have an operating microcomputer system. The system needs 
no maintenance other than the occasional cleaning of the printer and 
the tape heads on the cassette player. Clean the printer with a small 
brush to clear away the black dust that accumulates. Be careful not to 
damage the electrode (a small piece of wire running in the slot visible 
when the paper carrier is removed). Blow away the dust when you've 
brushed it from this slot. Keep your cassette tape heads clean and de- 
magnetised. 


If the printer doesn't work, first turn off the power. Then remove 
and re-insert the printer socket. Switch the power on again and try 
once more. The contacts on the printed circuit boards that the printer 


443 


socket connects with may need cleaning if the printer doesn't work or 
prints incorrectly. Clean the contacts with a proprietary contact cleaner 
or a pencil eraser. DO NOT use abrasives to clean these contacts. 
These are the only problems you should encounter with your system, 
as long as all plugs are well seated in their sockets. With the need to 
remove and re-insert the EAR socket when saving programs on 
cassette tape, you must take care to always re-insert the jack-plug 
properly each time. 


THE KEYBOARD 


The Spectrum keyboard has 40 keys arranged in 4 rows of 10. At first 
sight, it might appear similar to a typewriter keyboard, but on closer 
inspection you will see that keys have 5 or 6 functions or characters. In 
fact: 

Eight different characters and functions 

can be obtained with some keys! 


The keyboard contains: 

1 The digits 0 to 9 

2 The letters of the alphabet printed in upper and lower case 
(capitals) 

3 The complete BASIC language: 
— instructions 
— commands 
— arithmetic, conditional and logical operators 
— arithmetic functions 

4 Grammatical signs and symbols 

5 Special control keys 

6 Graphics symbols 


These are all called characters, and are on, below or above the keys 
used to access them. 

Notice that words like PRINT, LIST, RUN, etc are all printed on 
the keyboard and also appear on the screen with a single key press. 

The Spectrum’s ability to print complete words in the BASIC 
language at the press of a single key is called: 

SINGLE KEYSTROKE BASIC 

On most other computers you have to key in each letter of, for 
example, the instruction PRINT. This is obviously inefficient. The 
Spectrum is very powerful in this respect. The keyboard contains all 
the characters in the Spectrum’s character set, together with a few 
special keys. Some 200 ог so different characters are available. Some 
print to the screen, others are non-printing (e.g. DELETE). 


444 


CUP 


BLUE RED MAGENTA GREEN pn "S LOW m BLACK 


EDIT CAPS LOCK TRUE VIDEO INV. VIDEO GRAPHICS DELETE 
17 2 9 Rt RUP T ` „Лл в d Her 
DEF FN OPEN я CLOSE * MOVE ERASE POINT CAT 

г. 


ae c LA 0 E о 
БАЯ Mus R Á J; ы» IU 


VERIFY MERGE 


ES DATA 
AF i su ы ғ oe 
ENTER | 
sm oe Ht ЖӘ K 
CIRCLE VAL$ SCREEN$ а 
|с? UN B N M 


E ЕЗ | SPACE 
ЕР 2 oe и> C 2 V: Z Bs М os ЕЗ | SPACE 


PAPER FLASH BRIGHT OVER 


ANVSOVIO a WNYLIAdS 


r aunbi4 


THE CHARACTER TYPES ON THE SPECTRUM KEYS 


The Spectrum keyboard, to handle the enhanced version of Sinclair 
BASIC that runs on the Spectrum, has to accommodate more 
functions. This has been done by using basically the same layout as the 
ZX81 keyboard, but incorporating an additional shift key, which 
provides the capacity to access the additional colour, graphics, sound 
and microdrive functions which are present on the Spectrum but not on 
the ZX81. The Spectrum has an enhanced character set also, with 
additional text characters (@, ©, [, ],~, etc.) not in the ZX81 
character set. 

As this book deals with the ZX81 computer as well as the Spectrum, 
the treatment of additional facilities of the Spectrum is kept to this 
separate Spectrum Section, although some comments are made in the 
general text about these facilities where appropriate. However, you 
must learn how to access all the characters on the keyboard as a first 
priority. 

The keyboard is very complex and it will take some time for you to 
find your way around it with ease. It is best described in terms of how 
the characters are accessed and the cursors that indicate which mode 
the computer is in. The mode determines how the pressing of a key (a 
keystroke) is interpreted. Each key has multiple meanings for the 
computer, depending on the mode and whether either of the SHIFT 
keys (CAPS SHIFT and SYMBOL SHIFT) is being pressed at the 
same time as the keystroke occurs. 

You will notice that more characters are available from the top row 
of keys. These incorporate the colour control and graphics characters. 
(The inverse graphics are not shown on the key.) Here are examples of 
the two types of key: 


E Mode CAPS SHIFT 
CAPS SHIFT BLUE %- COLOUR CONTROL CHARACTER 


CHARACTER EDIT (in appropriate colour) 


(white) G Mode. Unshifted 
eh —— Graphics Character 
K and MODES G Mode Shift gives 
UNSHIFTED DIGIT Inverse Character ( IK in this case) 
CHARACTER 


K and L Modes SYMBOL 
SHIFT CHARACTER (red) 


E Mode SYMBOL SHIFT 
CHARACTER (Red) 


ROW 7 KEYS Example is the 1 key 


446 


/ E Mode UNSHIFTED CHARACTER (green) 


SIN 
L Mode UNSHIFTED 
жей K апа L Modes SYMBOL 
LETTER CHARACTER —> Q (= | - SHIFT CHARACTER 


(lower case) 
PLOT <. 
K Mode UNSHIFTED CHARACTER 


CHARACTER 


(upper case) ^ 


E Mode SHIFT CHARACTER (red) 


OTHER KEYS Example is Q key 


There are also the keys for ENTER, CAPS SHIFT, SYMBOL 
SHIFT, and the SPACE key (with BREAK printed above SPACE). 
See the keyboard diagram. We must now describe the modes the 
computer can be in, and the cursors that indicate the mode. There are 
also two other cursors which we will deal with here. 


MODES 


When inputting (keying in) program lines the position for the next 
entry is indicated by a cursor on the screen. The mode is indicated by 


the flashing cursors [E] . 


The mode (Keywords) and (Letters) may be used unshifted, 
with CAPS SHIFT or with SYMBOLS SHIFT. Letters of the 
alphabet are lower case unless the CAPS SHIFT key is used or the 
mode used. The mode (Capitals) is obtained by pressing CAPS 
SHIFT and CAPS LOCK simultaneously and is identical to the L 
mode apart from producing capitals (upper case) instead of lower-case 
letters. To return to mode press CAPS SHIFT and CAPS LOCK 
simultaneously. All letter inputs (REM statements, string inputs and 
assignments) in this text are in Capitals. You must use C-mode 
exclusively to get listings and printout of letters that correspond to 
those in this text. 


The mode (Graphics) accesses the graphics characters and may 
be obtained using the GRAPHICS key as an on-off switch. Press 
CAPS SHIFT and GRAPHICS simultaneously to enter mode. 


Repeat to cancel. 


447 


The mode (Extended) provides the equivalent of the function 
mode of the ZX81. It is obtained by pressing CAPS SHIFT and 
SYMBOLS SHIFT simultaneously and lasts for one character only. 
It may be used unshifted, with CAPS SHIFT or with SYMBOLS 
SHIFT. 


EFFECTS OF SHIFT KEYS ON MODES 














K mode — expecting a command i.e. Keyword mode. 
Unshifted - keyword (white word оп 3 bottom rows of 
keys) 
— digit (white digit on top row of keys) 
CAPS SHIFT - keyword (white word on 3 bottom rows of 
keys 
_ a ЖР (white word above top row of 
keys) 
SYMBOLS SHIFT - keyword or symbol (red symbol or word 
on key) 
L, mode — expecting a letter or a number i.e. Letters 
mode, giving the lower case letters. 
Unshifted — letter (white letter on 3 bottom rows of 
keys) 
— digit (white digit on top row of keys) 
CAPS SHIFT — letter (capitals) (white letter on 3 bottom 


rows of keys) 
— keyword (white word above top row of 
keys) 
SYMBOLS SHIFT - keyword or symbol (red symbol or word 
on key) 








C mode — identical with L mode but Capital letters 
are obtained with Unshifted letter keys. 


G mode — for accessing Graphics symbols. 
Unshifted — graphics character (in grey/white on keys 
1 to 8) 
— user defined graphic on keys A through 
U. (Not shown on keyboard.) 
CAPS SHIFT — inverse graphics character (reverse of 
symbol on top row of keys) 


SYMBOL SHIFT — same as CAPS SHIFT 


User defined graphics are dealt with in Unit W2. They are initially 
set as the capital letters À to U, which is what appears on the screen. 


448 


Note that DELETE works in G mode without CAPS SHIFT being 
pressed. 


E mode - Extended mode, accessing the function 
characters in green above the keys in 
bottom 3 rows, colour control characters 
on the top row,and the function or 
symbol characters in red below all keys. 

E mode lasts for one character only. 

Unshifted — function or symbol (in green above key 
for 3 bottom rows) 

— colour control (in colour above top row) 

CAPS SHIFT — function or symbol (in red below key for 3 
bottom rows) 

— colour control (in colour above key for top 
row) 

SYMBOLS SHIFT -function or symbol (in red below key for 3 
bottom rows) 

— function (in red below key for top row). 














The colour control characters print in a program line as the digit of the 
key that accesses them, i.e. they are coded 1-7 and 0. If they are 
accessed in E mode without INK or PAPER before them, the effect is 
to put colour control characters into the display. When unshifted, the 
colour control characters change the background (PAPER) colour of 
what is placed on the screen thereafter, and when CAPS SHIFT is 
pressed, the colour of the character (INK) is changed. 

Note: the main body of this text assumes no colours are used, since 
the ZX81 cannot produce colour. Colour on the Spectrum 15 dealt with 
in Unit W3. Experiment with colour all you want, but this text is 
primarily about BASIC programming, and it doesn’t matter what 
colour is on the screen for this! 


Exercise 


Access all the modes, 1.е. get each different cursor on the screen. Key 
in all the characters in each mode, first unshifted, then with CAPS 
SHIFT, and finally with SYMBOL SHIFT. You will have to enter the 
E mode again after each character. Watch what happens with TRUE 
VIDEO and INV VIDEO. Notice they reverse each other. Notice you 
can’t see a SPACE. Don’t press ENTER, just play around on the 
bottom lines of the screen. Notice that the line moves up the screen 
when it is filled. Press EDIT with CAPS SHIFT to clear the screen. 
You can’t harm the computer whatever you enter. Note that two words 
are abbreviated on the keyboard, but print in full- RAND and 
CONT. 


449 


SYNTAX ERROR CURSOR 


This cursor appears flashing in a line input at the bottom of the screen 
if the computer detects an error in the syntax of the line (i.e. finds an 
error in the ‘grammar’ of the BASIC language instruction input). It 
appears when ENTER is pressed to enter the line of program or the 
command into memory. The cursor appears before the last error in the 
line. There may be more than one error, but only one will be indicated 
at a time. Editing (making any change in the line) causes the cursor to 
disappear. It will reappear if necessary (error not corrected) when 


ENTER is pressed once again. 
CURRENT LINE CURSOR > 


This cursor appears after the line number of the last line entered into a 
BASIC program (the current line). If EDIT is pressed (CAPS 
SHIFTed 1) this line is brought down to the bottom of the screen. It 
can then be edited. 

In a program listing of the lines of a program displayed on the 
screen, the cursor may be moved to point to different lines by using the 
(CAPS SHIF Ted 6) and (CAPS SHIFTed 7) keys to move it down or 
up a program line. This is used to select a line for editing. 

An important point to note with regard to the keyboard is that the 
Spectrum has a repeat key action on all keys. If any key is held down, 
after a short time it will automatically repeat. 

We now give a table of the characters accessible on the Spectrum 
keyboard. Ignore the CODE information for now. This will be dealt 
with later. This table is the Spectrum equivalent of Appendix III, 
which deals with the ZX81. 


CHARACTER SET AND CODES TABLE 


This table, which is in alphabetical order, will enable the Spectrum 
user to quickly reference any character for: 


— its position on the keyboard in terms of a row and column 
‘parent key’ address (e.g. A is in the third row and first column 
of keys (3,1)) 

— the mode in which the function may be used (indicated by the 
flashing cursor on the screen) 

— which keys to press to obtain the function (here SHIFT means 
that ether the CAPS SHIFT or the SYMBOL SHIFT key will 
give the character) 


— the CODE of the character. 


450 


Character 


BEEP 
BIN 
BORDER 
BREAK 
BRIGHT 


C 


C 

CAPS LOCK 
CAPS SHIFT 
CAT 

CHR$ 
CIRCLE 
CLEAR 

CLS 

CODE 
CONTinue 
COPY 

COS 


D 

d 

DEF FN 
DELETE 


DIM 
DRAW 


Position 
on Keyboard 
Row, Column 


3,1 


` - ` 


` 


~ 


` 


Q3 NO NON h2 h2 CO CO 
О S OO — O N Oe 


` 


Mode(s) 


L C 


LC 


Aidt г сг mmm 


t= 


— 


шлш i p, EA г Gy E": 


ОО 


LC 


о О AR дагог 


451 


QQ 


To Obtain 


Press 


CAPS SHIFT 


SHIFT 
SYMBOL SHIFT 
SHIFT 
SYMBOL SHIFT 
SHIFT 
SHIFT 


SHIFT 


SHIFT 


SHIFT 


SHIFT 


CAPS SHIFT 
CAPS SHIFT 
SYMBOL SHIFT 


SHIFT 


CAPS SHIFT 


SYMBOL SHIFT 


CAPS SHIFT 


CAPS SHIFT 


CAPS SHIFT 
ENTER 
SYMBOL SHIFT 


rh — O < z Q > > > 


= = tN 2 % о 


CAPS SHIFT SPACE 


= 


ZU9e-puU жыс-<мшао NOOO 


— m tm tz 


pa ^! 


Code 


Character Position Mode(s) To Obtain Code 
on Keyboard Press 
Row, Column 


F 3,4 L CAPS SHIFT F 70 
C F 
Í 3,4 L F 102 
FLASH 4,5 E SHIFT Ұ 72% 
ЕМ 1,2 Е SYMBOLSHIFT 2 168 
FOR 3,4 K F 235 
FORMAT 1,10 E SYMBOL SHIFT 0 268 
G 3,9 L CAPS SHIFT G 71 
C G 
g 3.9 L С 103 
GOSUB 3,6 K а ЖИ 
GOTO 3,5 K G 236 
GRAPHICS 1,10 KLC CAPS SHIFT 0 - 
H 3,6 L CAPS SHIFT H т 
C H 
h 3,6 L H 104 
I 2,8 L CAPS SHIFT I 73 
C I 
i 2,8 L I 105 
IF 2,7 K U 250 
IN 2,8 E SHIFT I 191 
INK 4,3 E SHIFT АЖА 217 
INKEY$ 4,7 E N 166 
INPUT 2,8 K I 238 
INT 2,4 E R 186 
INVERSE 4,8 E SHIFT M 221 
J 3,7 L CAPS SHIFT J 74 
C J 
j ы 2 L J 106 
K 3,8 L CAPS SHIFT К 75 
C K 
k 3,8 L K 107 
L 3,9 L CAPS SHIFT L 176 
C L 
1 3,9 L L 108 
LEN 3,8 E E іл 
LET 3.9 K L 241 
LINE 3,9 K L 202 
LIST 1,3 K K 240 
LLIST 4,5 E V 225 
LN 4,2 Е 2 184 
LOAD 2,7 K J 239 
LPRINT 4,4 E C 224 
M 4,8 L CAPS SHIFT M 77 
C M 
m 4,8 L М 109 


452 


Character Position Mode(s) To Obtain Code 
on Keyboard Press 
Row, Column 


MERGE 2,9 E SHIFT £ 213 
MOVE 1,6 E SYMBOLSHIFT 6 209 
N 4,7 L CAPS SHIFT N 78 
C N 
n 4,7 L, N 110 
NEW 3,1 K A 230 
NEXT 4,7 K N 243 
NOT 5,2 KLC SYMBOLSHIFT S 195 
O 2,9 L, CAPS SHIFT O 79 
C O 
о 2,9 L O 111 
OPEN 1,4 E SYMBOLSHIFT 4 211 
OR 2-7 KLC SYMBOLSHIFT U 197 
OUT 2,9 Е SHIFT O 223 
OVER 4,7 E SHIFT N 222 
P 2,10 L CAPS SHIFT p 80 
C P 
2,10 L P 112 
PAPER 4,4 E SHIFT C 218 
PAUSE 4,8 K M 242 
PEEK 2,9 E O 190 
PI 4,8 E M 167 
PLOT 2,1 K О 246 
POINT 1,8 E SYMBOLSHIFT 8 169 
POKE 2,9 K О 244 
PRINT 2,10 K P 245 
о Д.Т L CAPS SHIFT О 81 
С Q 
q 2,4 L Q 113 
R 2,4 L CAPS SHIFT R 82 
C R 
r 2,4 L R 114 
RANDomise 2,9 K % 249 
READ 3,1 E ‚А 227 
REM 2,2 K E 234 
RESTORE 2,4 Е 5 229 
RETURN 2,6 K Ү 254 
RND 2,0 E Ж 165 
RUN 2,4 K R 247 
S 2,2 L CAPS SHIFT S 83 
C S 
S 3,4 L S 115 
SAVE 2,2 K S 248 
SCREEN$ 3,8 E SHIFT K 170 
SGN 3,4 E F 188 
SIN 2.1 Е Q 178 
SPACE 4,10 SPACE 22 


453 


Character 


SQR 
STEP 
STOP 
STR$ 


SYMBOLSHIFT 


N 


N 


WOOnNO сл > оо FS Ke © 


Position 
on Keyboard 


Row, Column 


42 


- м “ м » EJ ` 


EI 


к. — к л — һа ка ка ка — 
о О-О OF ы OO м = = 


- 


L C 
L C 


СӘС шшш бу Brot > > D m t Ca Es 


С сы DOE 


454 


To Obtain 


Press 


SYMBOLSHIFT 
SYMBOLSHIFT 


SYMBOL SHIFT 


CAPS SHIFT 


SYMBOL SHIFT 
SYMBOL SHIFT 


CAPS SHIFT 


CAPS SHIFT 


SHIFT 
SHIFT 


CAPS SHIFT 


CAPS SHIFT 


CAPS SHIFT 


CAPS SHIFT 


«wie Мих се: AS edie асс "obw < > Ü 


NNN 


ос со м СУ Q > ON © 


Code 


Character Position Mode(s) To Obtain Code 
on Keyboard Press 
Row, Column 


! 1,1 KLE SYMBOL SHIFT 1 33 
с 2,10 ELE SYMBOL SHIFT P 34 
# 1,3 KLG SYMBOL SHIFT 3 35 
$ 1,4 KLE SYMBOL SHIFT 4 36 
% 1,5 ELO SYMBOL SHIFT 5 37 
& 1,6 KLG SYMBOLSHIFT 6 38 
; 1,7 ELE SYMBOL SHIFT 7 39 
( 1,8 KL O SYMBOLSHIFT 8 40 
) 1,9 K LO SYMBOLSHIFT 9 41 
* 4,6 ELO SYMBOLSHIFT B 42 
4 3.8 EIL SYMBOLSHIFT K 43 
| 3,6 ELO SYMBOLSHIFT H 44 
© 4.7 KLC SYMBOLSHIFT J 45 
4,8 ELS SYMBOLSHIFT M 46 
/ 4,5 KLE SYMBOL SHIFT V 47 
4,5 ELO SYMBOLSHIFT Z 58 
: 2,9 É L O SYMBOLSHIFT O 59 
< 24 ELC SYMBOLSHIFT R 60 
» 3.9 KLC SYMBOLSHIFT L 61 
» 2.5 KI SYMBOL SHIFT T 62 
? 4,4 ELE SYMBOLSHIFT C 63 
Q 4,2 ELG SYMBOL SHIFT 2 64 
( 26 Е SHIFT Y 91 
) > 7 E SHIFT W 93 
% 3.3 E SHIFT D 92 
^ 3.6 ELO SYMBOLSHIFT H 94 
a 1,10 KLC SYMBOLSHIFT Q@ 95 
£ 4,3 ЕЗІ SYMBOLSHIFT X 96 
i 3.4 E SHIFT F 193 
| 3,5 Е SHIFT G 195 
| 2,3 E SHIFT S 124 
~ 3.1 E SHIFT A 126 
© 2,10 E SHIFT P 1⁄2 
ы 2,1 KLC SYMBOLSHIFT Q 199 
S 2.3 ELG SYMBOL SHIFT E 200 
<» 2,2 ELC SYMBOL SHIFT W 201 
ate 1,5 EL CAPS SHIFT 5 8 
кч 1,8 ELO CAPS SHIFT 8 9 
V 1,6 K L G CAPS SHIFT 6 10 
À 1:7 K LL G CAPS SHIFT ?. 4d 
| |] (space) 1,8 С 8 128 
Бы 1,8 G SHIFT 8 143 
k 1,1 с 1 129 
k= 1,1 G SHIFT 1 142 
Е | 12 G 2 136 
v 1,2 G SHIFT 9 141 
- i G 4, 191 
- 1,3 G SHIFT 3 140 
[m 1,4 G 4 132 
ГЕ 1,4 G SHIFT 4 139 
ГЕ 1,5 G 5 133 
H 1,5 G SHIFT 5 488 
" 1,6 G 6 134 


455 


Character Position Mode(s) To Obtain Code 


on Keyboard Press 

Row, Column 
m" 1,6 G SHIFT 6 137 
" 1,7 G 7 135 
B 1,7 G SHIFT 7 136 


Colour control characters have no special codes. They have the codes 
of, and print as, the digit of the key that accesses them. 
They are on keys 1 to 7 and 0. 


TRUE VIDEO is on key 1,3. This gives INK on PAPER 
colours (black on white on switch-on). 
INV. VIDEO is on key 1,4. This gives INVERSE, i.e. 


PAPER colour on INK colour 
background (white on black if not 
coloured). 


These use CODE 20 (a control code), and 
swap the current INK and PAPER 


colours. 


Other control codes are as follows: 


Control Character Code 
Comma for print spacing 6 
Number (in memory) 14 
Ink control 16 
Paper control 17 
Flash control 18 
Bright control 19 
Inverse control 20 
Over control 21 
Print At control 22 
Print Tab control 23 


These control characters are used to store required information in the 
attribute file (colour commands and characteristics of screen display), 
and the display file. They are followed by the values they take. 

User-defined graphics have codes 144 to 164 inclusive, and are set, 
unless redefined, as the capital letters À to U in sequence. See Unit W3 
for more information on this. 


W2: Additional Spectrum BASIC Functions 
This Unit covers the additional instructions and functions that are 


avallable in the Spectrum superset of Sinclair BASIC. First we will 
indicate the major differences. 


456 


SUMMARY OF ADDITIONAL SPECTRUM FACILITIES 


The following are the significant differences between the ZX81 and the 
Spectrum which have not been dealt with in the main body of the text: 


(1) 


(ii) 


(iii) 


(iv) 
(v) 


(vi) 


(vii) 


(viii) 


(ix) 


(x) 
(xi) 


The Spectrum gives a colour signal to the TV - see COLOUR 
in Section W3. Of course, it is still possible to use the machine 
on a black and white TV, where different shades of grey will be 
obtained when the colour commands are used. 

The Spectrum's character set differs from that of the ZX81 and 
includes lower case as well as capital letters- see 
CHARACTER SET and USER DEFINED GRAPHICS. 
The Spectrum's keyboard has additional characters and 
functions. You should now be familiar with the functions 
treated in the main text. Extended functions are dealt with a 
little later in this Unit. 

Simple sound production is available using the Spectrum's 
BEEP command - see SOUND in Section W3. 

The tape storing facilities represent a considerable 
improvement on those offered by the ZX81- see TAPE 
STORAGE below. The tape LOAD and SAVE speed is 
roughly 16k words in 100 seconds, and there is a facility to 
merge a program stored on tape with one in memory using 
MERGE. The VERIFY facility can be used to check that a 
program has saved correctly, as has been noted. 

Disc storage and file-handling capability with the microdrive 
will eventually be available on the Spectrum, loading 16k 
words per second - see OTHER KEYS below. 

Additional graphics commands are available to enable straight 
lines, arcs and circles to be drawn simply - see GRAPHICS in 
Section W3. 

The INPUT statement has additional features and 
instructions. READ, DATA and RESTORE are added - see 
below: PUTTING DATA INTO PROGRAMS. 

On the Spectrum it is possible to define your own numeric and 
string functions in а program -see USER DEFINED 
FUNCTIONS below. 

The Spectrum operates in a ‘fast mode’ at all times and is 
roughly four times faster than the ZX81. 

Multiple statements on a line are possible on the Spectrum 
with a colon(:) as a statement separator. For example: 


10 LETX-4:LETY26: LET Z=8 


Whilst this is a useful addition, multiple line statements can 
also be very confusing and their use should be minimised. This 
said, they can be useful for additional REM statements, 
assignments of related variables and conditional program 
sequences, and for the combination of graphics and colour 
commands. 


457 


The facility of being able to place a sequence of instructions 
after a conditional test is valuable. The sequence of BASIC 
Instructions following an IF...THEN will be executed IF the 
condition is TRUE. Control passes directly to the next line of 
the program if the condition is false. We can write: 


10 INPUT å 

20 IF а<1 OR a>9 THEN PRINT “Out of Range’’: 
GOTO 10 

30 PRINT a 


It is important to remember that you can only GOTO a line 
number and start at the beginning of that line. You cannot 
access the second or subsequent statements of a line with 
multiple statements. 

(xii) There is no SCROLL key on the Spectrum, but scrolling is 
done automatically by pressing any key (except N, STOP, 
BREAK) when ‘Scroll?’ appears on the screen. Making the 
Spectrum SCROLL in the same way as the ZX81 SCROLL 
command has been covered in the text. 

(xiii) It is important to note that CLEAR operates differently on the 
Spectrum than on the ZX81. CLEAR not only erases all 
variables in memory, but also resets RAMTOP апа 
RESTORE s as well as clearing the GOSUB stack. In fact you 
can use CLEAR on the Spectrum to reserve protected memory 
space above RAM TOP: using a command like CLEAR 23800 
sets RAMTOP to 23800. This cannot be done on the ZX81. 


You have seen the modifications required for the ZX81 programs to 
run on the Spectrum. Here is a summary for reference, to convert any 
programs you may come across in books or magazines. All programs in 
the text and the program library (Appendix VI) are annotated with any 
required Spectrum changes. 


ZX81 TO SPECTRUM PROGRAM CONVERSION 


There are relatively few things to bear in mind when converting a 
ZX81 program for the Spectrum. Of course, the ZX81 will not have 
included colour or sound in the programs, and these are aspects you 
can add for yourself. Note that ZX81 programs SAV Ed on cassette will 
not load into the Spectrum, even if no ZX81 specific commands have 
been used. 

Perhaps the first thing to note is that you must be in CAPS mode to 
produce listings and programs which are identical to those of the 
ZX81. (Use CAPS SHIFT with CAPS LOCK to stay in this mode 
when you switch on.) 

PLOT plots in high resolution — 256 x 176 pixels — whereas on the 
ZX81 the resolution was only 64 x 44. Thus as a general rule you сап 


458 


simply multiply by a factor of four to any PLOTted points in a ZX81 
program to obtain a working Spectrum version. Hence PLOT 4,10 on 
the ZX81 becomes PLOT 16,40 on the Spectrum. 

The Spectrum has no FAST and SLOW modes, as it runs in the 
equivalent of the SLOW mode all the time (always a screen display) 
but at the speed of a fast mode. Just omit program lines that contain 
the instructions FAST or SLOW. 

The Spectrum does not have SCROLL as a program instruction as 
the ZX81 does. To SCROLL the screen in a Spectrum program you 
need to POKE the location 23692 with a number greater than 1, or 
with —1. This temporarily disables the ‘SCROLL?’ request, and 
when followed by PRINTing AT the last line (line 21) on the screen the 
display will SCROLL. 

Thus the ZX81 line: 


200 SCROLL 


is replaced by 
200 POKE 23692, – 1 : PRINT AT 21,0; 


Raising a number to a power on the ZX81 uses the symbol ‘**’ 
whereas on the Spectrum we use ‘ ^". RAND іп ZX81 programs is 
that instruction on the Spectrum keyboard, but prints as 
RANDOMISE. 

POK Eing to the display file cannot be easily done, and the same is 
true of PEEK used to identify a character on the screen. To get around 
this we recommend using PRINT AT instead of POKEing the display, 
and SCREENS to replace PEEKing the display. Hence you will have 
to calculate what character cell position corresponds to any address in 
the ZX81's display file which is used in a program. Read the 
description of the ZX81 display file in Unit Q4 in order to find out how 
to do this. 

PEEKing the character table in RAM is done equally simply on the 
Spectrum, with the start of the character table being given by the 
following PEEKs, plus 256: 


PEEK 23606 + 256* PEEK 23607 


This is usually set at 15360 — but you can POKE these addresses and 
change the location at which the character table starts in memory. You 
can therefore create an entirely new character set in RAM and have the 
CHARS variable (stored in the locations above) point to 256 bytes 
below it. All other system variables on the ZX81 have equivalents on 
the Spectrum. This text has the system variables for both machines 
listed in Appendix V. 

Because of the amount of memory (6.5k) taken up for graphics on 
the Spectrum, you will find that a large program for the 16k ZX81 (of 
10k or so), will not fit into a 16k Spectrum. 48k Spectrum owners will 
of course have no problems with this, but if contemplating keying in a 


459 


long program with the smaller machine it is worth making a crude 
estimate of the program length, if the information is not given in the 
documentation. The number oflines in the listing (total, not numbered 
lines only), multiplied by 15 will give you a reasonable estimate (biased 
on the high side) of the program length in bytes. 


We will now go on to cover the additional Spectrum facilities and 
functions, other than those connected with Colour, Graphics and 
Sound, which are treated in Unit W3. 


TAPE STORAGE 


New keywords: VERIFY and MERGE. 
Associated new keywords: LINE, DATA, SCREEN$ 


(1) 


SAVING Information on Tape 


The SAVE key is used to save information on tape. This can be: 
(a) program and variables, (b) arrays, (c) bytes of memory 
(memory contents) 


When saving information on tape it is essential that the EAR piece jack- 
plug 15 removed from the tape recorder. 


(a) Programs and Variables 

SAVE ‘‘filnam’’ - saves programs and variables. 

SAVE ''filnam" LINE 10- saves programs and variables 
and when loaded next automatically runs itself from the given 
line number. 


(b) Arrays 

SAVE “alpha” DATA а()- вауев the numeric array а 
specified under the name alpha. 

SAVE “beta” DATA b$()-saves the string array b$ 


specified under the name beta. 


(c) Bytes 

SAVE “gamma” CODE 16384, 6912- saves the bytes 
specified. The first figure (in this case 16384) is the address of the 
first byte to be saved and the second figure (in this case 6912) is 
the number of bytes to be saved. 

The particular bytes specified above will save the ГУ picture, 
but a special key SCREENS is available to do this: 


SAVE ‘‘gamma’’ SCREEN$ 


460 


(i1) 


(iii) 


VERIFICATION of Information on Tape 
The VERIFY key is used to check the information saved on the 


tape against the information in the computer. 
VERIFY ‘‘filnam’’ - checks programs and variables 
VERIFY “аірһа” DATA a()-checks numeric array 
specified 
VERIFY “beta” DATA b$()-— checks string array specified 
VERIFY “сапта” CODE 16384, 6912 – checks bytes 
specified (first number – address of first byte, second 
number - number of bytes). 


LOADING Information from Tape 


The LOAD key is used to load new information from the tape, 
deleting any old information in the memory. 

LOAD ''filnam'' -loads program and variables specified 
(and automatically runs the program if the SAVE and LINE 
instructions were used to save the program). 

LOAD “alpha” DATA a() - loads numeric array specified by 
alpha as array a in memory. 

LOAD “Бега” DATA b$() - loads string array specified by 
beta as array b$ in memory. 

(N.B. If insufficient memory is available, an error message 


occurs and the old information in memory is not deleted.) 

LOAD “сатта” CODE 16384, 6912 loads the bytes specified (first 
number is the address of the first byte, second number is the number of 
bytes). 

LOAD “gamma” SCREENS is an alternative for the particular 
bytes specified above which contain the TV picture. 


(iv) 


MERGING Programs 


The MERGE key is used to combine a program already in 
memory with a program on tape (it may not be used on arrays or 
bytes). 

MERGE ‘‘delta’’ — adds the program delta (stored on tape) to 
the program already in memory, overwriting any program lines 
and variables in memory which are at the same line numbers or 
have the same variable name as those on tape. For example: 


Program in memory: 


10 PRINT “hello” 


20 PRINT 
30 PRINT ‘‘goodbye’’ 
40 PRINT 


50 PRINT “ела” 


461 


Program ‘‘delta’’ on tape: 
19 PRINT "no" 

20 PRINT “уез” 

60 PRINT ‘‘repeat’’ 


MERGE “delta” results in the program: 

10 PRINT “по” 

20 PRINT “yes” 

30 PRINT ''goodbye" 

40 PRINT 

50 PRINT “епа” 

60 PRINT ‘‘repeat’’ 
Note the restriction on the use of MERGE. It can only be used for 
numbered program lines. These can have defined arrays or variables 
that are transferred with the program, but direct data (array values or 
bytes) is not MERGEable. See Units T11 and T12 for storing data, 
and remember that as long as there is one program line, MERGE will 
work. 


PUTTING DATA INTO PROGRAMS 


New keywords: READ, RESTORE and DATA 
Extended function for INPUT key 


(1 INPUT Statement 


10 INPUT A$ allows input of one string 
20 INPUT A,B,C,D allows input of four 
numbers 


30 INPUT ‘‘Enter your name’’, N$ allows the part within 
inverted commas to be 
printed at the bottom of 
the screen. 


If we key in: 


10 LET M$ =‘‘SPECTRUM’’ 
20 INPUT (‘‘I am’’;m$;‘‘.’’); ‘‘Your name?’’, y$ 


these two lines will produce at the bottom of the screen: I am 
SPECTRUM. Your name? “ cursor ” 

It is also possible to use INPUT AT in a similar way to 
PRINT AT: 


10 DIM a$(5) 


20 INPUT АТ 0,0; a$(1); АТ 1,0; a$(2); AT 2,0; a$(3); АТ 
3,0; a$(4); АТ 4,0; а%(5). 


462 


(11) 


(iii) 


This will result in the inputs being placed on separate lines (note 

what these co-ordinates mean). The lower part of the screen will 

move up to allow all input lines to be on screen. (The upper part 

remains unaltered until the lower part would start to write on the 

same line — the upper part then starts to scroll.) 

10 INPUT LINE a$ allows input of a string without the 
computer inserting quotes around the 
cursor. 


READ and DA TA 


These keys allow data to be stored internally within the 
program. For example: 


10 READ a,b,c 
20 PRINT a,b,c 
30 DATA 10,20,30 


The computer looks at all lines containing DATA statements 
and puts them sequentially into a data bank. A pointer is 
associated with the data bank and is initially set to the first item. 


10 20 30 


^ 
When the program reaches a line with a READ statement, the 
first data item is allocated to the variable (i.e. a = 10) and the 
pointer moves to the second item and so on. So b = 20 and 
c= 30. 
Note (i) DATA items are separated by commas 
(1) variables in READ statements are separated by 
commas 

(ii) string data items must be in inverted commas 

For example: 


10 READ a$,b,c$,d 
20 PRINT a$,b,c$,d 
30 DATA ‘‘smith’’, 90 
40 DATA ‘‘jones’’, 60 


RESTORE 


The RESTORE statement may be used to alter the position of 
the pointer. For example: 


10 READ a$,b 


20 RESTORE 
30 READ c$,d 


463 


40 PRINT a$,b,c$,d 
50 DATA ‘‘smith’’, 90, ‘‘jones’’, 60 


The effect of line 20 is to reset the pointer to the first item. Thus 
a$ = ‘‘smith’’, b = 90, c$ = ‘‘smith’’, d = 90. It is also possible to 
use RESTORE with a line number in which case the pointer is 
reset to the first item of the data statement of that line (or 
following lines). For example: 


10 READ a$,b 

20 RESTORE 100 

30 READ c$,d 

40 PRINT a$,b,c$,d 

50 DATA ''smith'', 90, ‘‘jones’’, 60 
100 DATA ‘‘brown’’, 100, ‘‘white’’, 120 
200 DATA ''black'', 8, '*yellow'', 6 


This will allocate a$ = “smith”, Ь-90 and c$ = “brown”, 
а= 100 (whereas 20 RESTORE gives c$ = smith", d = 90 
and 20 RESTORE 200 gives c$ = ‘‘black’’, d = 8). 

If CLEAR is used on the Spectrum, it also does a RESTORE 
on the data. 


USER DEFINED FUNCTIONS 
New keywords: DEF FN and FN 


The user can define up to 26 numeric and 26 string functions in any 


program. 
A numeric function is named FN followed by a single letter — e.g. 


FN Z. 

A string function is named FN followed by a single letter and $ – e.g. 
FN A$. 

It is necessary to define the function using a DEF FN statement (i.e. 
by pressing the DEF FN key). For example: 


10 DEF FN а(х)-х%3 
20 PRINT FN a(3) 


Line 10 defines the function and line 20 would give 3° = 27. For strings: 


10 DEF FN q$(a$) = a$ (2 to 6) 
20 PRINT FN q$(‘‘harrison’’) 


Line 10 defines a string function and line 20 would give ‘arris’. 
You may also use functions with several variables: 


464 


5 LET a=10: LET b= 20 
10 DEF FN p(x,y,z) =а*хфћ 2 +ЬЪ*ућ 2+2 
20 PRINT FN p(1,2,3) 
30 PRINT 
40 PRINT FN p(3,2,1) 


Note that any constants occurring (in this case a,b) are not included in 
the FN; only the variable values are specified (in this case x, y and z). 
Thus line 20 gives 93 and line 40 gives 171. 


CHARACTER SET AND USER DEFINED GRAPHICS 


(1) Character Set 


The character set consists of 256 characters each having a code 
between @ and 255. The set consists of: 


Control characters (code 0 to 31) 

ASCII characters (plus the non-standard £ and ©) 
Spectrum graphics symbols 

User-defined graphics 


The program given below will print out the complete character 


set (excluding the control characters): 
10 FOR n=32 ТО 255: PRINT CHR$ n;: NEXT n 


(ii) User defined graphics 


These are the letters A to U in graphics mode. They initially 
print as these letters (in capitals), until defined. They enable one 
to print a given shape in a character cell by pressing a single key. 
EXAMPLE: Fill the screen with dogs. Begin by producing a 
dog shape which fills a character cell when GRAPHICS D is 
pressed and then display the dogs across the screen. 


(1) Fill in appropriate squares in 8 by 8 cell 
(11) Allow 1 for ink, 0 for paper 
(ui) Put appropriate numbers in data statements 


Binary Decimal 
жа жк l l ` dx 11100001 225 
11100010 226 
11111100 252 
00111100 60 
00111100 60 
00111100 60 
00100100 36 
00100100 36 





465 


со PORE USR 2 2 Ж 

Se NEXT n _ (: 

то DATA 25,226, 252,52, Ба, еб, З 
Б ЗР 
-- z | p 

20 REM screenfFut of dogs 

эр BORDER а: POPER 2: INK е: LC 
LS 

ip FOR ісе TO ге STEF 2 

лла FOR c=@ ТО за STEP = 


15а PRINT BT ipi 
130 NEXT с 
142 NEXT £ 


The BIN key allows you to enter binary numbers —1.e. BIN 
11100001 is equivalent to 225 in the DATA statement (line 65). 
The plot of the user-defined graphic in the 8 x 8 grid, expressed 
in binary form, can thus be centred directly with the use of BIN 
into the DATA statement: 

70 DATA BIN 11100001, BIN 11100010, etc. 


OTHER KEYS 


The following keys will only operate when the Sinclair microdrive and 
the RS 232 (standard printer) interface become available: 


OPEN ж, CLOSE * , MOVE, ERASE, CAT and FORMAT. 


The keys IN and OUT are associated with I/O ports (input and output 
ports) and enable the SPECTRUM to communicate with peripheral 
devices. The equivalent commands used by the operating system run 
the ZX Printer. They are beyond the scope of the present text. The use 
and format of these instructions will be specified in the documentation 
of any equipment using them. 


W3: Colour, Graphics and Sound 
COLOUR 


(i) BORDER AND PAPER 


The screen is divided into two areas referred to as: 
BORDER (the outer part) and PAPER (the central area). (24 
lines of 32 characters.) 
The instructions BORDER and PAPER are used to define the 
colours of the areas. 

The following colours are available: 


) black 
1 blue 


466 


(11) 


red 
magenta 
green 
cyan 
yellow 
white 


-] OQ) ол © h2 


Magenta is a purple colour, and cyan is light blue. 
Unless otherwise specified, both BORDER and PAPER are 
white. The colour of border and paper can be changed to any of 
the eight normal colours. For example: 
BORDER 4: the border becomes green on pressing the 
ENTER key 

PAPER 2: no change occurs on pressing the ENTER 
key (it merely cancels PAPER command 
already existing). Press the ENTER key 
again and the centre becomes red. 

(On a black and white ТУ the above numbers correspond to 
the order of brightness). 

Both instructions can be used in programs: 

10 BORDER 2: PAPER 6 
These are global commands defining the whole border and 
paper areas. PAPER may be used as a specific command (see 


below). 
PICTURE 


The picture area affected by the global PAPER instruction 
consists of 24 lines each of 32 positions, i.e. 24 x 32 = 768 


character cells. The screen that can normally be printed to is 22 


lines of 32 character cells. The character cells have printing 
characteristics (attributes) which may be specified. 
Each character cell consists of 8 x 8 dots and has two colours 


associated with it: 


INK (foreground colour) 
PAPER (background colour) 


Normally each character cell has black ink and white paper. 

In addition, each character cell also has а brightness 
attributed with BRIGHT (normal ог extra-bright) cor- 
responding to BRIGHT 0 and BRIGHT 1 and the attribute 
FLASH with the possibility of no-flash or flash corresponding to 
FLASH 0 and FLASH 1. For example: 

10 PAPER3:INK6: BRIGHT 0 : FLASH 1 

would result in background magenta, foreground yellow, 
normal brightness and flashing. Flashing characters alternate 





467 


(111) 


the ink and paper colours. In addition, 8 can be used with all 
four statements meaning transparent (i.e. left as previous); 9 
can be used with PAPER and INK meaning contrast. PAPER 
will be dark (black) if INK 15 specified as a light colour (colours 0 
to 3), light (white) if INK specified as a dark colour (colours 4 to 
7). INK produces contrasting PAPER in the same way. 





INVERSE, OVER AND ATTR 


The statements INVERSE and OVER may also be used to 


control the dot pattern printed in the character cells. 


inverse or normal i.e. INVERSE 1 (inverse video) or 
INVERSE 0 (normal video) 

over or normal i.e. OVER 1 (overprints the new 
character on top of the old) 
OVER 0 (normal) 


All the statements in (11) and (iii) may be used in conjunction 
with PRINT and INPUT commands and also with graphics 
commands such as PLOT and DRAW. For example: 


10 INPUT INK 2; FLASH 1; ‘‘What is your name?’’; N$ 
20 PRINT PAPER 6; N$ 


which will result when run in ‘What is your name?’ flashing in 
red and white and the name input (in black and white) is then 
printed out in black on yellow. If not specified, the PAPER 
instruction assumes the contrasting INK, FLASH @ and 
BRIGHT 0. 

The attributes of any character cell (i.e. PAPER, INK, 
BRIGHT and FLASH) on the screen may be determined using 
the ATTR key, which returns a number made up as follows: 


FLASH on (128), normal (0) + 
BRIGHT on (64), normal (Ø) + 
PAPER (8* colour) + 
INK (colour) 


Thus, 10 PRINT ATTR (19,20) would give the number 162 if 
the character cell at (19,20) is flashing (128), normal (0), green 
paper (32) and cyan ink (2). 

The TRUE VIDEO instruction gives the INK colour on 
PAPER colour background. This may be changed to 
INV.VIDEO (PAPER colour on INK colour). All succeeding 
printed character squares have the attributes shifted as if 
INVERSE had been used. 


468 


EXAMPLE 1 


This is a simple program to display the colours available and to show 
the effect of the transparency and contrast commands. 


5 REM colours 

10 FOR п-1 TO 22: FOR p=0 TO 7 

20 PAPER P: PRINT " е; 

30 МЕХТ р: МЕХТ п 

40 PAUSE 100 

45 REM transparency апа contra 
st 

50 INK 9: PAPER 6: PRINT AT 0, 
0; 

60 FOR n=l TO 66: PRINT "colou 
rings";: NEXT D: PRINT 

70 PAPER 7: INK 0: BRIGHT @ 

80 PAUSE 100 


EXAMPLE 2 


This is a simple program drawing coloured straight lines with different 
separations. 
Line 30 - gives а black border. 
Line 320 – gives paper and ink colours (selected at random, 
excluding black and white). 
Line 200 - resets paper and border to white, ink to black for listing 
etc. after program has been run. 


Notice how colours are character cell dependent not pixel dependent. 
This program clearly shows this effect. 


38 BORDER @ 

40 FOR х-й ТО 254 STEP 2 

50 PLOT 128,88: DRAW -127+x,-8 

7 

60 NEXT x 

65 GO SUB 300 

76 FOR y=0 TO 174 STEP 3 

88 PLOT 128,88: DRAW 127,-87+y 
90 NEXT y 

95 GO SUB 300 
100 FOR z=0 ТО 254 STEP 2 
110 PLOT 128,88: DRAW 127-z,87 
120 NEXT Z 
125 GO SUB 300 
130 FOR a=0 TO 174 STEP 3 
140 PLOT 128,88: DRAW -127,87-a 


150 NEXT a 

200 PAPER 7: INK 0: BORDER 7 

210 STOP 

300 LET i=(5*RND+1): LET p-INT 
(S*RND)+1 


310 IF i=p THEN GO TO 10 
320 PAPER p: INK i 
330 RETURN 


469 





GRAPHICS 
New keywords: DRAW, CIRCLE, POINT 


The screen is 22 lines by 32 columns – i.e. 704 character cells for 
graphics use. Each character cell consists of 8 by 8 dots (called pixels). 
Thus the pixel co-ordinates go from (0,0) bottom left-hand corner to (255, 
175) the top right-hand corner. 


Colour Graphics 


You can do graphics in colour but remember that the pixels in any 
one character cell can only be either of the two colours corresponding to 
the current ink and paper values for the character cell. 

For example, let’s attempt to draw three circles one black, one blue and 
one red: 


10 INK 2: CIRCLE 40,40,30 (red circle) 
20 INK 1: CIRCLE 60,60,40 (blue circle) 
30 INK 0 : CIRCLE 50,50,40 (black circle) 


This example shows that colour graphics is possible but can only be 
handled with great care. It is important to be clear about character cells 
as opposed to pixels. For example, you can draw three circles one black, 
one blue and one red: 


10 INK 2 : CIRCLE 70,70,70 (red circle) 
20 INK 4: CIRCLE 70,70,50 (blue circle) 
30 INK 0 : CIRCLE 70,70,30 (black circle) 


Graphics Commands 


PLOT X.Y — inks in the pixel at the point (X,Y) 
DRAW X1,Y1 -inks in the line from the point specified previously to 


470 


the point X1 pixels to the right and Y1 pixels up from 
it. For example: 


10 PLOT 20,30 - plots point (20,30) 

20 DRAW 50,60 — draws line from point (20,30) 
to the point (20 50,30 + 60), 
i.e. (70,90). 


DRAW Х2,Ү2,А- draws an arc of a circle from the previously spec- 
ified point to the point X2 pixels to the right and 
Y2 pixels up from it with an angle A radians 
(anticlockwise). For example: 


10 PLOT 30,30 
20 DRAW 60,60 
30 DRAW 80,80, PI 


CIRCLE X,Y,A draws a circle centre (X,Y) and radius A 

POINT (X,Y) will give @ if pixel at (X,Y) is paper colour and 1 if ink. 
For example: 

10 CIRCLE 40,40,30 - draws circle centre (40,40) and radius 30 
20 PRINT POINT (40,40)- pixel paper - 0 

30 PRINT POINT (70,70)- pixel ink - 1 


The commands INVERSE and OVER may be used with the graphics 


commands. For example: 


PLOT INVERSE 1 wil put paper colour at pixel 
PLOT OVER 1 will change ink to paper at pixel 


There is no UNPLOT on the Spectrum. We must use INVERSE or 
OVER. PLOT OVER 1 or PLOT INVERSE 1 effectively unplot the 
pixel. DRAW OVER 1 may be used to rubout a line while preserving 
the original information; compare result of program 1 with that of 
program 2. 


18 FOR п-1 IO 22 
2@ PRINT 


за NEXT n 

ге PLOT @,@: DRAN 255,175 

435 STOF 

оа PLOT @,@: BRAW INVERSE 1; 25 
2,175 


ла FOR n= =1 TO 22 


за PLOT @,@: DRAW INVERSE i:25 
5,125 Е š w 


Try this one-line program: 
10 PLOT 65,27: DRAW OVER 1; 120,120,49*3*PI 
Try different values in place of 49. 


EXAMPLES 


1 Use of PLOT and DRAW commands (straight lines) 
This program makes use of these statements to draw a histogram 
by drawing a series of rectangles. 
Lines 70 and 80 produce a rectangle as shown: 


- W 


x, yo 


10 REM Histogram using DRAW 

20 READ х0,у0: LET x=x@ 

25 REM Coordinates of LHS 

30 READ w,n 

35 REM Width and number of uni 
ts 

40 FOR j=1 TO n 

50 READ h 

60 REM Unit height 

70 PLOT x,y0 

80 DRAW м,0: DRAW @,h: DRAW -w 
,9: DRAW 0,-П 

90 LET x=x+w 

100 NEXT 1 

105 DATA 5,5,20,12 

110 DATA 12,45,67,98,134,167,17 
0,136,124,87,46,20 


472 


2 Use of DRAW command (arcs of circles) 
This program produces a pattern by drawing four sets of 
semicircles. The basic plotting line is illustrated by the diagram 
of the effect of line 40. This is repeated within a series of four 
loops. 


п. 
-бӨха а 


10 LET a=0 

20 FOR n=129 TO 254 STEP 3 

30 LET а=а+1 

40 PLOT n,0: DRAW -6*a,0,PI 
50 NEXT n 

60 LET b= 

76 FOR n=129 TO 254 STEP 3 

80 LET b=b+l 

90 PLOT n,175: DRAW -6*b,@,-PI 
100 NEXT n 
110 LET c=0 
120 FOR п-90 ТО 174 STEP 3 

130 LET с=с+1 
140 PLOT 0,п: DRAW 0,-5%с,-РІ 
150 NEXT n 

160 LET d=0 

176 FOR n=90 TO 174 STEP 3 
180 LET d=d+l 

190 PLOT 255,n: DRAW @,-6*d,PI 
200 NEXT n 


und VN 
Akaros tirga 
25840471515, 
қосулы Ту 
= 
УЫ, 
“4 a. ы % 4 
ЖАЗАСЫ 
NN М У NN 
Г] тҮ a -—"" T 
МУМ z == 
N m LS m mh 5 






x ay 5 4 Ux 1 VANY š “ ? i % 

52) 25 ENO 
ORE WOW Arita 
Aadi Eek ^ n Te 
«саг ШЕН t EPLET Pe ESL 

rigat Al . 45 
patatie И * Не 
азга БИН I NW D BI 
quati, 27777 ji ИР 1 $A; 


473 


Try inserting the following lines to see the effect of colour (note 
graphics is pixel but colour is character cells). 


5 INK 2 
55 INK 5 
105 INK 6 
155 INK 3 


Use of CIRCLE command 
This command draws a circle and by varying the position of the 
centre and the radius of the circle we can obtain an acceptable 
drawing of a cone: 

5 REM Draw a cone 


10 READ i,p,b 
15 REM ink,paper,border 


20 READ cr 

25 REM radius of cone 

30 CLS : INK i: BORDER b: PAPE 
Кр: CLS 

40 LET x-50 


50 FOR r=cr TO 1 STEP -1 
60 CIRCLE х,90,г 

70 LET x=x+3 

80 NEXT r 

90 DATA 1,4,6 

100 DATA 50,3 





4 Use of user-defined functions for graph plotting 


The program below illustrates the use of the DEF FN and FN 
instructions in plotting graphs. Line 5 defines the function. Line 
10 bypasses the subroutines (lines 20 to 100) and the main 
program first defines a=5 (line 120), then calls the first plot 
subroutine (lines 20 to 50), which uses a loop to define values of 
x. Line 30 makes the variable b equal to COS x and passes 
control to the subroutine at line 200 to evaluate y using the FN 
(y) instruction in line 200. Note this is a nested subroutine. Line 
210 plots the results with suitable scale factors. On return to the 
subroutine the next value of x is taken and the process repeated. 
On return to the main program, the second subroutine, lines 70 
to 100, is called, to plot the SIN x function by making b = SIN x. 

The variable a is redefined to equal 15 in line 150 on 
completion of the first two plots, and the subroutines are called 


474 


In sequence again. Note the capability to define a function using 
variables, and then define the values of the variables as 
appropriate. In this case, two values (COSx and SINx) are given 
to b, and the amplitude a is defined as first 5, then 15. Four plots 
are produced from the one user-defined function of line 5. 


> DEF ҒЫ чіхі-ьға 
120 


2 ее то 
15 REM #xFUNCTION ONE PLOT жж 
ек *£*+SUBRGUT INE жж 


20 FOR x=@ ТО 25 STEP .1 
Зе LET b-COS x: GO SUB > 


SS REH xxEND FN ONE 3135 жж 
+++» X X <£ < kX x < ЖЖ 


26 
d 
Sa REM ##FUNCTION TUO PLOT zx 
= #X SUBROUTINE жж 


1@5 НЕН xxEND FN THO Svs жж 
+++ ++ ++ X 2 3 x £ ЖЖЖ 


110 БЕН #+#+++ ++ +++ kE x #5 5+ + + x= + 
жүнін PROGRAM жж 


17@ GO SUB 7о 
180 STOP 
185 REM ##END MAIN PROGRAMS 
$ £ x 3 X X X X X X X x x 3 35 £ £ £ x = 
19а REH ЖӘМШБВКБООТІМЕ-СЕН САТЕ + ж 
FUSING FN AND PLOT ex 
200 LET u=FN u (x; 
210 PLOT x2#1@,yYs#3+56 
азге RETURN 


230 REM rxzENDSUB FUNCTION USE#+ 
SREFES TEESE ЕЕЕ ЕЕ ET EF FFE 


SOUND 
New keyword: BEEP 


BEEP 6, 2 produces a note of duration 6 seconds and a pitch 2 semitones 
above middle C. The sound is fairly quiet; however fractional changes 
in pitch are available and it is possible to tune it to different 
instruments. To obtain the even-tempered scale of C major: 


BEEP 1,0 : BEEP 1,2: BEEP 1,4 : BEEP 1,5: BEEP 1,7: 
BEEP 1,9 : BEEP 1,11 : BEEP 1,12 


475 


The short program below gives some idea of the useful musical range 
and how it may be used for sound effects. 


5 REM MusicaLl ranae 
30 RERD pPil,Pzz 

15 REM lowest and highest freq 
го FOR п=рӣ TO pz 

=e BEEP ,5,п 
ар PRINT AT (i13-n»;353,inei-21 


со NEXT n 

55 DATA -25,308 

Ба PAUSE 200: CLS 

70 REM $0 — effect 

ва LET х-.1 E 
aa FOR N-60 TO 20 STER 73. 
SS PRINT AT i380-n.23?.22. 
100 BEEP .@5,n 

130 LET x=x = 

De NEXT n ie 
іза BEEP .05,-25: EEEF .1,50 


476 


APPENDIX I 


ZX81 BASIC Summary 
CONVENTIONS 


nor m or p 


numeric expression 

string expression 

expression (string or numeric) 
variable name 

statement 

indicates an optional item 
indicates a string instruction 


Numeric variables are first character a ietter, then any alphanumeric characters. 


String variables are À to Z, followed by $. 


OPERATING COMMANDS 
LOADs 


SAVE s 
RUN [n] 
CLEAR 
NEW 
STOP 
CONT 
FAST 


SLOW 


INPUT/OUTPUT INSTRUCTIONS 


INPUT V 
INKEY$ 


LIST [n] 

PRINT [ell,e][;e][AT n,m;][TABn;] 
CLS 

PLOT m,n 

UNPLOT m,n 

LLIST [n] 

LPRINT [el]L,elL;e]l TAB n;] 
COPY 


OTHER INSTRUCTIONS 
POKE n,m 

PEEK n 

PAUSE n 

REM 


LET V[$] =e 


Load a program from tape. String may be null 
(‘*’’) (Loads first program) 

Save a program on tape 

Run program [starting at line n] 

Resets all variables in program 

Clears out program and variables 

Stops program execution 

Starts execution after BREAK or STOP 
Screen not displayed until end, PAUSE, 
INPUT, SLOW. Computes only. 

Screen displayed continuously, whilst 
computing 


Input numeric or string variable from keyboard 
Reads current input character. Does not wait for 
key to be pressed. 

Displays program [starting from line n] 

Print on screen 

Clears the screen 

Plot % graphic char. | 0< = m< = 63 horizontal 
Unplot pixel 0< = n< = 43 vertical 
List program on printer [starting from line n] 
Print on line printer 

Print a copy of screen on printer 


Store the value m in memory location n. 
O< = m< = 255. 

Returns the value stored in memory location n 
Halts program for п/50ѕесопаѕ (п/60 in U.S.). 
If n>32767 then pauses until key pressed. 
(n<65535) 

REMARK - comments. Ignored in program 
execution. 

Assigns the value of e to V 


477 


DIM У[$] (n[,m]) 


RAND [n] 
RND 

GOTO n 
GOSUB п 
RETURN 

IF e THEN <s> 


FOR V =n TO m [STEP p] 
<s> 

[<s>] 

NEXT V 


TRIG FUNCTIONS 


SIN n 

COS п 
TAN n 
ASN n 
ACS n 
ATN n 


NUMERIC FUNCTIONS 


EXP n 
LN n 

SOR n 
INT n 
ABS n 
SGN n 
PI (m) 


STRING FUNCTIONS 


LEN s 
CHR$ n 
CODE s 
STR$ n 
VAL s 
+ 


EXPRESSIONS 
PRIORITY 


12 () 


11 any function 

10 жж 

9 -в 

8 ж 

?4 

6 +- 

5 -,<>,<,>,<«,>- 


Dimensions array n by m (numeric), n strings of 
length m if string 

Random number seed 

Function returns a random number n. f = n<1 
Transfers control to line n 

Go to Subroutine at line n 

Return from subroutine to line after last GOSUB 
If e is true THEN statement s is done, if e is 
false then s is not done. For e see expressions. 
Evaluates as TRUE = 1, FALSE = 0 

V is any single letter control variable. 

m,n,p any numeric expressions. STEP 1 is 
assumed if STEP not specified 

Increments V by STEP. Goes to next line if 
V>m (m2n) or V&m (n2m). 


Sine n 

Cosine n 

Tangent n 

Arc Sine n (ARCSIN on keyboard) 

Arc Cosine n (ARCCOS on keyboard) 
Arc Tangent n (ARCTAN on keyboard) 
n evaluated as radians 


Exponent n or е" 

Log. nor ln n 

Square root of n 

Integer of n (rounds down) 

Absolute value of n 

1 if n is positive, 0 if zero, — 1 if negative 


3.1415927 


Length of string s 

Character of code n (single character string) 
Code of first character in string s 

Convert numeric expression to String 
Convert string to numeric expression 

String concatenation 


bracketed expressions 
functions 
exponentiation 

unary minus 
multiplication 

division 

addition & subtraction 
equality & inequality 


478 


4 NOT 
3 AND 
2 OR 


ZX Spectrum Basic Summary 
CONVENTIONS 


n, m or p 
5 

е 

V 

<s> 

[ ] 


logical inversion 
logical AND 
logical OR 


numeric expressions 

string expression 

expression (string or numeric) 
variable name 

statement 

indicates an optional item 


Numeric variables are first character a letter then any alphanumeric characters. 
String variables are a letter followed by $. 


OPERATING COMMANDS 


BREAK 
CLEAR 
CLEAR n 
CONT 
DELETE 
EDIT 
ENTER 
GRAPHICS 
LOAD s 


LOAD s CODE n,m 
LOAD s DATA V() 


MERGE s 


NEW 

RUN [n] 

SAVE s 

SAVE s LINE n 


SAVE s CODE n,m 
SAVE s SCREEN $ 
SAVE s DATA V() 
STOP 

VERIFY s 


VERIFY s CODE n,m 
VERIFY s DATA V() 


OTHER INSTRUCTIONS 
BIN n 


DATA el, ЖЗ, 
DEF FN 


interrupts operation e.g. execution, printer 
clears variables 

changes position of RAMTOP 

continues execution after BREAK or STOP 
allows deletion of character 

allows editing of current line 

line entered into program 

puts into graphics mode 

clears program and existing variables and loads 
program specified from tape. (string may be ‘‘”’ 
in which case the first program is loaded) 
loads m bytes into memory starting at address n 
loads specified array (string or numeric) into 
memory 

merges program s with the one already in 
memory 

clears program and variables 

runs program [starting at line n] 

Saves program and variables on tape 

saves program so that a LOAD is automatically 
followed by a GOTO n 

saves m bytes starting at address n 

saves the picture on tape 

saved specified array (string or numeric) on tape 
stops program execution 

verifies that program specified has been saved 
on tape 

verifies bytes specified have been saved on tape 
verifies array specified has been saved on tape 


puts binary number n into decimal 

separates multiple statements on a line 

gives data items within a program 

user-defined function definition. It must be 


479 





FN 


DIM V[$](n[,m]) 


FOR V =n TO m [STEP p] 
NEXT V 

GOSUB n 

RETURN 

GOTO n 

IF e THEN <s> 


IN n 

OUT n,m 

LET VI$] = е[$] 
PAUSE n 
PEEK n 


POKE n,m 
READ У1[$], V2I$], ... 


USR n 


GRAPHICS 


followed by the name (single letter) of the string 
or numeric function and the definition - e.g. 
FNa(x,y,z)=xP3+y$44+z45 

calls up the user-defined function. Arguments 
enclosed in brackets — e.g. FNa(3,5,7) 
dimensions array V. Numeric arrays of n rows 
[and m columns]. String array of n strings each 
of length m characters. Multi-dimension arrays 
possible 

V a single letter, initiates a loop 

V a single letter, completes loop 

go to subroutine at line n 

returns from subroutine to main program 
transfers control to line n 

executes statement when the condition is met. 
(There may be several numeric and logical 
conditions) 

returns the byte read from I/O port n 

writes value m to I/O port n 

assigns value e to variable V 

makes program wait a specified time (n = 0 waits 
for ever, n=1 to 65535 waits n/5@ seconds in 
UK and п/60 seconds in US) 

returns the value stored in the memory location 
n 

stores value m in memory location n 

allocates variables the values specified in DATA 
statements. 

calls the machine-code routine starting address n 


22 lines with 32 columns available. 
Each character cell consists of 8 by 8 pixels. 
256 horizontal points and 176 vertical points. 


CIRCLE n,m,p 
DRAW n,ml,pl 


PLOT n,m 


POINT (n,m) 


COLOURS: 


- black 

— blue 

— red 

- magenta 
green 

— cyan 

— yellow 

— white 


- O: сл > Ó rO в 
| 


draws а circle centre (n,m) and radius р 

draws line [arc] from previous specified point to 
a point relative n horizontal and m vertical 
[turning through angle p radians (anticlockwise 
if p positive)] 

Plots a pixel 

@< = n< = 255 horizontal 

0< = m< = 175 vertical 

returns 0 (paper colour) or 1 (ink colour) of the 
pixel (n,m) 


480 


Picture is divided into 768 (24 lines of 32 columns) character cells. 


ATTR (n,m) 
BORDER n 
BRIGHT n 
FLASH n 
INK n 
INVERSE n 
OVER n 


PAPER n 


SOUND 


BEEP n,m 


INPUT/OUTPUT INSTRUCTIONS 


CLS 
COPY 
INKEY$ 


INPUT VI$] 


INPUT LINE V$ 

LIST [n] 

LLIST [n] 

LPRINT [е][,е][;е]ГТАВ n] 


PRINT [elL,el[;elLATp,ml][ TAB m] 


TRIG FUNCTIONS 


ACS n 
ASN n 
ATN n 
COS n 
SIN n 

TAN n 


(n evaluated in radians) 
NUMERIC FUNCTIONS 
ABS n 


EXP n 
INT n 


gives colour attributes of the character cell (n, m) 
@< = n< = 23 lines 
0< = m< = 31 columns 
makes border specified colour (n = 0 to 7) 
controls brightness (n = 0 normal, п = 1 bright, 
n = 8 transparent) 
controls flashing (n = 0 normal, п = 1 flash, п = 8 
no change) 
makes ink (foreground) specified colour (n = 0 to 
7, n=8 transparent, n = 9 contrast) 
controls dot pattern (п= 0 normal, n=1 
inverse) 
controls overprinting (п= 0 normal, n=1 
mixing) 
makes paper (background) specified colour 
(n = to 7, n = 8 transparent, n = 9 contrast) 


produces sound of duration n seconds and pitch 
m semitones above (or below) Middle C. 


clears the screen 
prints out copy of screen on the printer 
reads current input character. Does not wait for 
key to be pressed. 
input numeric [or string] variable from 
keyboard 
allows string variable to be input without quotes 
displays program [starting from line n] 
lists program on printer [starting from line n] 
prints out on line printer 
prints on screen 

22 lines @© = p< = 21 

32 columns 0< = т< = 31 


Arc cosine п 
Arc sine n 
Arc tangent n 
Cosine n 
Sine n 
Tangent n 


absolute value of n 
exponential n (i.e. e") 
integer of n (rounds down) 


481 





LN ñ 

PI 

RAND [n] 
RND 


SGN n 
SOR n 


STRING FUNCTIONS 


CHR$ п 
CODE s 
LEN s 
STR$ n 
VAL s 
VALS s 


natural logarithm of n (i.e. log n or In n) 

n, 3.1415927 

random number seed 

function returns a random number between 0 
and 1 

returns 1 if n is positive, 0 if zero, — 1 if negative 
square root of n 


character of code n 

code of first character of string s 

returns length of string s 

converts numeric expression into string 
converts string expression into numeric 
converts s to a string expression (strips off 
quotes) 


PRIORITY see table for ZX81. 


482 


APPENDIX II 


ZX81 Error Codes 


Code Meaning 


0 


Successful completion, or jump to line number 
bigger than any existing. A report with code @ does 
not change the line number used by CONT. 


The control variable does not exist (has not been set 
up by a FOR statement) but there is an ordinary 
variable with the same name. 


An undefined variable has been used. 

For a simple variable this will happen if the variable 
is used before it has been assigned to in a LET 
statement. 

For a subscripted array variable it will happen if the 
variable is used before it has been dimensioned in a 
DIM statement. 

For a control variable this will happen if the variable 
is used before it has been set up as a control variable 
in a FOR statement, when there is no ordinary 
simple variable with the same name. 

For a numeric INPUT, will occur if non-numeric 
input received. 

Subscript out of range. 

If the subscript is negative, or bigger than 65535 
then error B will result. 

Not enough room in memory. Note that the line 
number in the report (after the /) may be incomplete 
on the screen, because of the shortage of memory: 
for instance, 4/20 may appear as 4/2. 


No more room on the screen. CONT will make 
room by clearing the screen. 

Arithmetic overflow: calculations have led to a 
number greater than about 10, 

No corresponding GOSUB for a RETURN 


statement. 


You have attempted INPUT as a command (not 
allowed). 
STOP statement executed. CONT will not try to 
re-execute the STOP statement, but continues from 
next line. 


Invalid argument to certain functions. 


Integer out of range. When an integer is required, 
the floating point argument is rounded to the nearest 
integer. If this is outside a suitable range then error 
B results. 


483 


Situations 


Any 


NEXT 
Jumping into a loop. 


Any 


Subscripted variables 
(Lists and arrays) 
Substrings 


LET, INPUT, DIM, 
PRINT, LIST, PLOT, 
UNPLOT, FOR, 
GOSUB. Sometimes 
during function 
evaluation. 


PRINT, LIST. 


Any arithmetic. Division 
by zero is common cause. 
RETURN. No STOP 
statement before 
subroutine is common 
cause. 


INPUT 


STOP 


SOR, LN, ASN, ACS, 
VAL 

RUN, RAND, POKE, 
DIM, GOTO, GOSUB, 
LIST, LLIST, PAUSE, 
PLOT, UNPLOT, 
CHR$, PEEK, USR 





С The text of the (string) argument of VAL does not VAL 


form a valid numerical expression. 


D (i Program interrupted by BREAK. At the end of any 
statement as the program 
runs or in LOAD, SAVE, 


LPRINT, LLIST or 


COPY. 
(ii) The INPUT line starts with STOP. INPUT 
F . The program name provided is the empty string. SAVE 


Spectrum Error Codes 


The report has a code number or letter (so that you can refer to the following table), a 
brief message explaining what happened and the line number and statement number 
within that line where it stopped. (A command is shown as line 0. Within a line, 
statement 1 is at the beginning, statement 2 comes after the first colon or THEN, and 
so on.) 

The behaviour of CONTINUE depends very much on the reports. Normally, 
CONTINUE goes to the line and statement specified in the last report, but there are 
exceptions with reports 0, 9 and D. 

Here is a table showing all the reports. It also tells you in what circumstances the 


report can occur. 


Code Meaning 


0 


ОК 

Successful completion, ог jump ќо а line number 
bigger than any existing. This report does not 
change the line and statement jumped to by 
CONTINUE. 


NEXT without FOR 

The control variable does not exist (it has not been 
set up by a FOR statement), but there is an ordinary 
variable with the same name. 


Variable not found 

For a simple variable this will happen if the variable 
is used before it has been assigned to in a LET, 
READ or INPUT statement, loaded from tape or 
set up in a FOR statement. For а subscripted 
variable it will happen if the variable is used before it 
has been dimensioned in a DIM statement or loaded 
from tape. 


Subscript wrong 

A subscript 1s beyond the dimension of the array, or 
there are the wrong number of subscripts. If the 
subscript is negative or bigger than 65535, then error 
B will result. 


Out of memory 

There is not enough room in the computer for what 
you are trying to do. If the computer really seems to 
be stuck in this state, you may have to clear out the 
command line using DELETE and then delete a 
program line or two (with the intention of putting 
them back afterwards) to give yourself room to 
manoeuvre with — say - CLEAR. 


484 


Situations 


Any 


NEXT 
Jumping into a loop is a 
common cause. 


Any 


Subscripted variables 
(arrays), 
Substrings 


LET, INPUT, FOR, 
DIM, GO SUB, LOAD, 
MERGE. Sometimes 
during expression 
evaluation. 


Code Meaning 


5 


Out of screen 

An INPUT statement has tried to generate more 
than 23 lines in the lower half of the screen. Also 
occurs with PRINT AT 22,... 


Number too big 
Calculations have led to a number greater than 
about 1055. 


RETURN without GO SUB 
There has been one more RETURN than there were 
GO SUB. 


End of file 


STOP statement 
After this, CONTINUE will not repeat the STOP, 
but carries on with the statement after, or next line 


after, STOP. 


Invalid argument 
The argument for a function is no good for some 
reason. 


Integer out of range 

When an integer is required, the floating point 
argument is rounded to the nearest integer. If this is 
outside a suitable range then error B results. 


Nonsense in BASIC 
The text of the (string) argument does not form a 
valid expression. 


BREAK - CONT repeats 

BREAK was pressed during some peripheral 
operation. 

The behaviour of CONTINUE after this report is 
normal in that it repeats the statement. Compare 
with report L. 


Out of DATA 
You have tried to READ past the end of the DATA 
list. 


Invalid file name 
SAVE with name empty or longer than 10 


characters. 


No room for line 
There is not enough room left in memory to 
accommodate the new program line. 


STOP in INPUT 

Some INPUT data started with STOP, or- for 
INPUT LINE - BREAK was pressed. 

Unlike the case with report 9, after report H 
CONTINUE will behave normally, by repeating the 
INPUT statement. 

FOR without NEXT 

There was a FOR loop to be executed no times (e.g. 
FOR n=1 TO 0) and the corresponding NEXT 


statement could not be found. 


485 


Situations 


INPUT, PRINT AT 


Any arithmetic. Division 
by zero is common cause. 


RETURN. No STOP 
statement before a 
subroutine is common. 


Microdrive, etc, 
operations only. 


STOP 


SOR, LN, ASN, ACS, 
USR (with string 
argument) 

RUN, RANDOMIZE, 
POKE, DIM, GO TO, 
GO SUB, LIST, LLIST, 
PAUSE, PLOT, CHR$, 
PEEK, USR (with 


numeric argument) 


VAL, VAL$ 


LOAD, SAVE, VERIFY, 
MERGE, LPRINT, 
LLIST, COPY. Also 
when the computer asks 
scroll? and you type 


READ 
SAVE 
Entering a line into the 


program 


INPUT 


FOR 


Code Meaning 


J 


K 


Invalid I/O device 


Invalid colour 
The number specified is not an appropriate value. 


BREAK into program 

BREAK pressed, this is detected between two 
statements. The line and statement number in the 
report refer to the statement before BREAK was 
pressed, but CONTINUE goes to the statement 
after (allowing for any Jumps to be done), so it does 
not repeat any statements. 


RAMTOP no good 
The number specified for RAM TOP. is either too big 
or too small. 


Statement lost 
Jump to a statement that no longer exists. 


Invalid stream 


FN without DEF 

User-defined function 

Parameter error 

Wrong number of arguments, or one of them is the 
wrong type (string instead of number or vice versa). 
Tape loading error 

A file on tape was found but for some reason could 
not be read in, or would not verify. 


486 


Situations 


Microdrive, etc., 
operations only 


INK, PAPER, 
BORDER, FLASH, 
BRIGHT, INVERSE, 
OVER; also after one of 
the corresponding control 
characters 


Any 


CLEAR; possibly in 
RUN 


RETURN, NEXT, 
CONTINUE 


Microdrive, etc, 
operations only 


FN 


FN 


VERIFY, LOAD or 
MERGE 


APPENDIX III 


ZX81 Character Codes by Keyboard Arrangement 


Note: Character codes for both the ZX81 and the Spectrum are listed in order of code 
number in Section P, and an alphabetic list for the Spectrum is included in Unit W-1. 


1. KEYBORD CHARACTERS 


CHARACTER CODE CHARACTER CODE 
PLOT 246 NEW 230 
UNPLOT 252 SAVE 248 
REM 234 DIM 233 
RUN 247 FOR 235 
LINE2 RAND 249 LINES GOTO 236 
RETURN 254 GOSUB 237 
IF 250 LOAD 239 
INPUT 238 LIST 240 
POKE 244 LET 241 
PRINT 245 
COPY 255 
CLEAR 253 
CONT 232 
CLS 251 
LINE4 SCROLL 231 
NEXT 243 
PAUSE 242 
BREAK — 


TOTAL 26 Characters. 
May be entered when mode cursor appears. 
Obtained by pressing desired key. 


2. SHIFT CHARACTERS 


CHARACTER CODE CHARACTER CODE 
EDIT 117 ж 5 192 
AND 218 OR 217 
THEN 299 STEP 224 
TO 223 <= 219 
LINE1 «€ 114 LINE2 <> 221 
113 >= 220 
À 112 $ 13 
> 115 ( 16 
GRAPHICS 116 ) 17 
RUBOUT 119 es 11 


487 


CHARACTER CODE CHARACTER CODE 


STOP 227 : 14 
LPRINT 223 қ 25 
SLOW 228 ? 15 
FAST 229 / 24 

LINE: 3  LLIST 226 LINE4 * 23 
“. 216 < 19 
- 22 > 18 
+ 21 i 26 
= 20 £ 12 
FUNCTION 121 


TOTAL 39 Characters. 
Obtained by pressing and keys together. 


3. LETTER CHARACTERS 


CHARACTER CODE CHARACTER CODE 


1 29 А 38 
2 30 S 56 
3 31 D 41 
4 32 F 43 

LINE 1 5 33 LINE3 G 44 
6 34 H 45 
7 35 J 47 
8 36 K 48 
9 37 L 49 
0 28 NEWLINE 118 

(ENTER) 

о 54 SHIFT 
W 60 Z 63 
F 49 K 61 
R 55 C 40 

LINE? Т 57 LINE4 V 59 
Y 62 B 39 
U 58 N 51 
I 46 M 50 
O 52 27 
Р 53 SPACE 0 


TOTAL 39 Characters. 
May be entered when mode cursor appears. 
Obtained by pressing the desired key. 


488 


4. GRAPHICS CHARACTERS 


CHARACTER CODE CHARACTER CODE 


F| 1 ЕЕ 8 
[4 2 FS 10 
Lal 135 ы 9 
а) 4 ЫШ 138 
ІЛМЕ 1 u 5 LINE 3 E 137 
ыш 131 ES 136 
= 3 inverse — 150 
. 133 inverse + 149 
Inverse = 148 
ma 129 inverse : 142 
М 130 Inverse ; 153 
F 7 Inverse ? 143 
LINE 2 = 132 LINE 4 inverse / 152 
= 6 Inverse * 151 
Fg 134 inverse < 147 
inverse $ 141 inverse > 146 
Inverse ( 144 Inverse , 154 
Inverse ) 145 Inverse £ 140 
inverse "' 139 


TOTAL 36 Characters. 


Entered in mode, obtained by pressing |SHIFT| |GRAPHICS | keys. 
Character obtained by pressing [SHIFT] [CHARACTER 


5. INVERSE GRAPHICS CHARACTERS 


INVERSE INVERSE 


CHARACTER ` CODE CHARACTER CODE 
1 157 Q 182 
2 158 W 188 
3 159 E 170 
4 160 R 183 
LINE 1 5 161 LINE2 Т 185 
6 162 Y 190 
7 163 U 186 
8 164 I 174 
9 165 О 180 
0 156 P 181 


489 


INVERSE INVERSE 


CHARACTER CODE CHARACTER ` CODE 
A 166 Z 191 
S 184 x 189 
D 169 C 168 
F 171 V 187 

LINE3 G 172 LINE4 B 167 
H 173 N 179 
J 175 M 178 
K 176 | 155 
i, 177 128 

(SPACE) 


TOTAL 38 Characters. 
May be entered in mode obtained by keys. 


Obtained by pressing desired keys. 


6. FUNCTION CHARACTERS 


CHARACTER CODE CHARACTER CODE 


SIN 199 LN 205 
COS 200 EXP 206 
TAN 201 AT 193 
INT 207 INKEY$ 65 
LINE2 AND 64 LINE4 NOT 215 
STR$ 213 n(PI) 66 
CHR$ 214 
CODE 196 
PEEK 211 
TAB 194 
ARCSIN 202 
ARCCOS 203 
ARCTAN 204 
LINE 3 SGN 209 
ABS 210 
SOR 208 
VAL 197 
LEN 198 
USR 212 


TOTAL 25 Characters. 


Мау be entered іп [Е] mode obtained by pressing [ SHIFT | 
key. 

Characters obtained by pressing desired character key. 

The mode operates for only one character input. 


490 


APPENDIX IV 


Use of Cassette Tapes 


The following information concerns the use of cassette tapes for program storage and 
retrieval. Other details of personal tape library practice can be found in the main text. 


1 


New tapes: Always ‘fast forward’ and ‘rewind’ a tape completely before use for 
program storage. This ensures an even winding and tension. If you have the 
patience, running the tape one way in ‘play’ mode after fast forward and reverse is 
desirable. 

Do not use the first 15 or 20 seconds of any tape. Most tape problems of coating 
loss and stretch occur in this portion of the tape. 

Always rewind tapes fully after use, so as to not leave tape with program data 
exposed. Never touch the surface of the tape. Before inserting a tape in the cassette 
player, take up the slack in the tape (using a finger or a pencil) by turning one 
drive wheel until the other moves. 

Always replace tapes in the correct library boxes immediately after use. Leave the 
label side (if only one label) showing. 

Tapes with programs meant to be permanent should have the tags removed to 
prevent accidental erasure. The holes can always be covered with sticky tape if you 
decide in the future to record over a program. 

Clean the tape-recorder heads after 2 or 3 hours’ running time with a head cleaner 
cassette or head cleaner fluid. De-magnetise heads every 10 or 12 hours’ running. 
Leave long gaps (at least 20 seconds) between programs, if more than one program 
is on a tape. Note the tape counter readings for beginning and end of each 
program. Remember that the tape counter is not highly accurate. You can use the 
TV screen to find a gap between programs, watching for the thick black lines of a 
program load display change to the thin diagonal lines of a ‘blank tape’ display. 
Loading problems. These are notes for the ZX81 user. No problems should be 
encountered with the Spectrum in this respect. For each individual ZX81/cassette 
system, no problems should be encountered with SAVEing and LOADing 
programs with the TONE control set high, and the VOLUME at 3/4 volume. The 
characteristics of tape recorders vary somewhat, however, and problems may be 
encountered in LOADing programs which have been SAVEd on a different 
recorder. Here is a sequence to be followed if a program proves difficult to LOAD. 


A Set the TONE control for maximum treble (‘High’). 

B Set the VOLUME to about three-quarters of the maximum. 

С Rewind tape to the beginning. 

D Type: LOAD “A” - i.e. any letter/word except the program name. 
Press PLAY on the cassette, then NEWLINE (ENTER) on the 7Х81. 
When the thin, slightly sloping black lines change to the programs' typical 
thick black and white lines, with approximately equal black and white 
bands, with the white crossed by vertical black lines: 

(a DECREASE THE VOLUME until this changes back to the THIN 
lines. 

(b Now INCREASE THE VOLUME, noting where the THICK black 
and white program lines eventually seem to become more unsettled 
or predominantly black. 

Also if you listen to the recording you may be able to notice when the 

volume is too high and causes distortion. 

E  Setthe VOLUME midway between these two points (a) and (b). 
Rewind tape. 

Type: LOAD “(Тһе program name)”. 

Press PLAY on the cassette, then NEWLINE (ENTER) on the ZX81. 

If the screen suddenly clears before the program should end, this may 

mean volume is still too low. 


491 


The ZX81 may need to be re-set by pulling out the d.c. supply plug and 
re-inserting it if the cursor does not return to the screen, either by itself or 
when BREAK is used. 
LOAD again, slightly increasing the volume, after rewinding the tape. 
If you cannot get a definite, THICK black and white line pattern even at 
full volume then your recorder may not be powerful enough to load from 
the signal strength on this specific tape. Test this by using another 
recorder, or recorder/ZX system. Once the program has LOADed, SAVE 
it on to a tape in your own recorder. 
Turn off cassette recorder and take the EAR/MIC leads out of the ZX81 
before swapping recorders, or else you may cause the system to crash 
whilst taking out and re-inserting the plugs. 

9 NEVER place a tape on top of the TV monitor. This can affect the signals stored 

on the tape because of the electromagnetic field generated by the TV. 


492 


APPENDIX V 


System Variables — ZX81 


Notes: 


X The system may crash if the variable is poked. 
N Poking the variable will have no lasting effect. 


S The variable is saved by SAVE. 


The number in column 1 is the number of bytes storing the variable. For two bytes, 
the first one is the less significant byte. To poke a value M to a two-byte variable at 
address N use: 


To peek its value, use the expression 


Notes 


X1 
X2 


N1 
N2 


Address 
16384 


16385 
16386 


16388 


16390 
16391 


16393 
16394 


16396 
16398 


16400 
16402 
16404 
16406 


POKE N (M - 256*INT(M/256)) 
POKE N + 1, INT M/256 


PEEK N + 256*PEEK(N + 1) 


Name 


ERR_NR 


FLAGS 
ERR_ SP 


RAMTOP 


MODE 
PPC 


VERSN 
Е PPC 


D FILE 
DF CC 


VARS 
DEST 

E LINE 
CH ADD 


Contents 


1 less than the report code. Starts off at 255 
(for — 1), so PEEK 16384, if it works at all, 
gives 255. POKE 16384, N can be used to 
force an error halt: N < = 14 gives one of the 
usual reports, 15 <=N<=34 or 99 
< = N<127 gives an non-standard report, 
and 35 < = N < = 98 may disrupt the display 
file. 

Various flags to control the BASIC system. 
Address of first item on machine stack (after 
GOSUB returns). 

Address of first byte above BASIC system 
area. You can poke this to make NEW 
reserve space above that area or to fool CLS 
into setting up a minimal display file. Poking 
RAMTOP has no effect until one of these 
two is executed. 

Specified K, L, F or G cursor. 

Line number of statement currently being 
executed. Poking this has no lasting effect 
except in the last line of the program. 

Q Identifies ZX81 BASIC in saved programs. 
Number of current line (with program 
cursor). 

See Unit O4. 

Address of PRINT position in display file. 
Can be poked so that PRINT output is sent 
elsewhere. 

See Unit U2. 

Address of variable in assignment. 

See Unit U2. 

Address of the next character to be 
interpreted: the character after the argument 
of PEEK, or the NEWLINE (ENTER) at 
the end of a POKE statement. 


493 


16408 


16410 
16412 
16414 
16415 


16417 
16418 


16419 
16421 
16423 
16424 
16425 
16427 
16429 
16430 
16432 
16434 


16436 


16438 
16439 
16440 


16441 
16442 
16443 
16444 


16477 


16507 


X PTR 
STKBOT 
STKEND 


BERG 
MEM 


not used 
DF SZ 

5 TOP 
LAST K 
MARGIN 
NXTLIN 
OLDPPC 
FLAGX 
SIRLEN 
T ADDR 
SEED 


FRAMES 


COORDS 


PR CC 


S POSN 
CDFLAG 
PRBUFF 


MEMBOT 


not used 


Address of the character preceding the § 


marker. 
See Unit U2. 


Calculator's b register. 
Address of area used for calculator's 
memory. (Usually MEMBOT, but not 


always.) 


The number of lines (including one blank 
line) in the lower part of the screen. See Unit 
Q4. 

The number of the top program line in 
automatic listings. 

Shows which keys pressed. 

Debounce status of keyboard. 

Number of blank lines above or below 
picture: 55 in Britain, 31 in America. 
Address of next program line to be executed. 
Line number to which CONT jumps. 
Various flags. 

Length of string type 
assignment. 

Address of next item in syntax table (very 
unlikely to be useful). 

The seed for RND. This is the variable that 
is set by RAND. 

Counts the frames displayed on the 
television. Bit 15 is 1. Bits @ to 14 are 
decremented for each frame sent to the 
television. This can be used for timing, but 
PAUSE also uses it. PAUSE resets to 0 bit 
15, and puts in bits @ to 14 the length of the 
pause. When these have been counted down 
to zero, the pause stops. If the pause stops 
because of a key depression, bit 15 is set to 1 
again. 

x-coordinate of last point PLOTted. 
y-coordinate of last point PLOTted. 

Less significant byte of address of next 
position for LPRINT to print at (in 
PRBUFF). 

Column number for PRINT position. 

Line number for PRINT position. 

Various flags. Bit 7 is on (1) during compute 
and display mode. 
Printer buffer 
NEWLINE). 
Calculator memory area; used to store 
numbers that cannot conveniently be put on 
the calculator stack. 


destination in 


(33rd character is 


494 


System Variables — Spectrum 


Notes: 


X The system may crash if the variable is poked. 
N Poking the variable will have no lasting effect. 

The number in column 1 is the number of bytes in the variable. For two bytes, the 
first one is the less significant byte. To poke a value M to a two-byte variable at address 


N use 


and to peek its value, use the expression 


Address 


23552 
23560 
23561 


23562 


23563 


23565 
23566 


23568 
23606 


23608 
23609 
23610 


23611 
23612 
23613 
23615 
23617 


23618 
23620 


23621 


POKE N(M - 256% INT(M/256)) 
POKE N + 1, INT M/256 


POKE N + 256* PEEK (N + 1) 


Name 


KSTATE 
LAST K 
REPDEL 


REPPER 


DEFADD 


K DATA 
TVDATA 


STRMS 
CHARS 


RASP 
PIP 
ERR NR 


FLAGS 
TV FLAG 
ERR SP 
LIST SP 
MODE 


NEWPPC 
NSPPC 


PCC 


Contents 


Used in reading the keyboard. 

Stores newly pressed key. 

Time (іп 50ths of a second - in 60ths of a 
second in N. America) that a key must be 
held down before it repeats. This starts off at 
35, but you can POKE in other values. 
Delay (in 50ths of а second - in 60ths of a 
second in America) between successive 
repeats of a key held down: initially 5. 
Address of arguments of user-defined 
function if one is being evaluated; otherwise 
0. 

Stores 2па byte of colour controls entered 
from keyboard. 

Stores bytes of colour, AT and TAB controls 
going to television. 

Addresses of channels attached to streams. 
256 less than address of character set (which 
starts with space and carries on to the 
copyright symbol). Normally in ROM, but 
you can set up your own in RAM and make 
CHARS point to it. 

Length of warning buzz. 

Length of keyboard click. 

1 less than the report code. Starts off at 255 
(for - 1) so PEEK 23610 gives 255. 
Various flags to control the BASIC system. 
Flags associated with the television. 
Address of item on machine stack to be used 
as error return. 

Address of return address from automatic 
listing. 

Specifies K, L, C, E or G cursor. 

Line to be jumped to. 

Statement number in line to be jumped to. 
Poking first NEWPPC and then NSPPC 
forces a jump to a specified statement in a 
line. 

Line number of statement currently being 
executed. 


495 


Notes 


N2 


N2 


кі ка к ка М) 


Address 
23623 


23624 


23625 


23627 
23629 
23631 
23633 


23635 
23637 
23639 
23641 
23643 
23645 


23647 


23649 
23651 
23653 
23655 
23656 


23658 
23659 
23660 


23662 
23664 


23665 
23666 


23668 
23670 
23672 
23675 
23677 
23678 


23679 
23680 


Name 


SUBPPC 


BORDCR 


E PPC 


VARS 
DEST 
CHANS 
CURCHL 


PROG 
NXTLIN 
DATADD 
E LINE 
K CUR 
CH ADD 


X PTR 
WORKSP 
STKBOT 
STKEND 


BREG 
MEM 


FLAGS2 


DF SZ 


S TOP 


OLDPPC 
OSPCC 


FLAGX 
STRLEN 


T ADDR 


SEED 


FRAMES 


UDG 


COORDS 


P POSN 
PR CC 


Contents 


Number within line of statement being 
executed. 

Border colour * 8; also contains the attributes 
normally used for the lower half of the 
screen. 

Number of current line (with program 
cursor). 

Address of variables. 

Address of variable in assignment. 

Address of channel data. 

Address of information currently being used 
for input and output. 

Address of BASIC program. 

Address of next line of program. 

Address of terminator of last DATA item. 
Address of command being typed in. 
Address of cursor. 

Address of the next character to be 
interpreted: the character after the argument 
of PEEK, or the NEWLINE (ENTER) at 
the end of a POKE statement. 

Address of the character after the Syntax 
error marker. 

Address of temporary work space. 

Address of bottom of calculator stack. 
Address of start of spare space. 

Calculator's b register. 


Address of area used for calculator's 
memory. (Usually MEMBOT, but not 
always.) 

More flags. 


The number of lines (including one blank 
line) in the lower part of the screen. 

The number of the top program line in 
automatic listings. 

Line number to which CONTINUE jumps. 
Number within line of statement to which 
CONTINUE jumps. 

Various flags. 
Length of 
assignment. 
Address of next item in syntax table (very 
unlikely to be useful). 

The seed for RND. This is the variable that 
is set by RANDOMIZE. 

3 byte (least significant first), frame counter. 
Incremented every 1/50th second (U.K.) or 
1/60th second (U.S.). 

Address of 1st user-defined graphic. 
x-coordinate of last point plotted. 
y-coordinate of last point plotted. 
33-column number of printer position. 

Less significant byte of address of next 
position for LPRINT to print at (in printer 
buffer). 


string type destination in 


496 


Notes 


Address 


23681 
23682 


23684 
23686 
23688 
23689 
23690 
23692 


23695 


23694 


23695 


23696 
23697 
23698 


23728 
23730 
23732 


Name 


ECHO E 
DF CC 
DFCCL 
S POSN 


SPOSNL 


SCR CT 


ATTR P 


MASK P 


ATTR T 


MASK T 
P FLAG 
MEMBOT 


RAMTOP 
P-RAMT 


Contents 


Not used. 

33-column number and 24-line number (in 
lower half) of end of input buffer. 

Address in display file of PRINT position. 
Like DF CC for lower part of screen. 
33-column number for PRINT position. 
24-line number for PRINT position. 

Like S POSN for lower part. 

Counts scrolls: it is always 1 more than the 
number of scrolls that will be done before 
stopping with scroll? 

Permanent current colours, etc. (as set up by 
colour statements). 

Used for transparent colours, etc. Any bit 
that is 1 shows that the corresponding 
attribute bit is taken not from АТ ТК P, but 
from what is already on the screen. 
Temporary current colours, etc (as set up by 
colour items). 

Like MASK P, but temporary. 

More flags. 

Calculator's memory area; used to store 
numbers that cannot conveniently be put on 
the calculator stack. 

Not used. 

Address of last byte of BASIC system area. 
Address of last byte of physical RAM. 


497 





| 











a en a E 
Е Bd inte Е. BL SANE - 


ion wt 
Е | т ys - y 
rw б» А e ° я Е 
* - TIN» Ë "ae © ee et 
j* E. g “Hee oa’ 7 90° 
та) * gs s тыр “ma = 
41 те vv 
v vas? dt 27» a Е e" s». 
o mE eL = “ 
ауа B Be 
“,.”.- 
*(* T i 
Tor D 
““ “us т game ч © c Z 
Е "> 5 9 
“p Н & a 
e 5 
А Р Bn A LIS š - 2 g’ 
E f LU 
Е еу =, E UE Sis 
Ae F: og 
е. da ^g 
s ç =: % J ер с 
2 * š 8 4 e 





APPENDIX VI 


PROGRAM LIBRARY 


This appendix contains applications and utility programs and routines, and games. 
Some of these have been referred to in the main text. Due to lack of space, the 
programs are not fully documented. 


1. Polar 


Program produces a polar coordinate graph of the function entered as A$. This must be 
an expression using A as the dependent variable. Since a common cause of failure of 
the VAL function (giving the error code A) on the ZX81 is the exponentiation function, 
this is noted and a way of avoiding it given. The angle increment (in radians) is entered 
as DA. The appropriate scale factor can be experimented with. If you get a small 
cramped plot (or even a single pixel), increase the scale factor. If the plot goes off the 
screen, you are informed that the scale factor needs reducing (line 250). Polar 
coordinate plots can be thought of as an X,Y plot with the X axis bent into a circle, and 
the Y axis plot point defined as a distance R (radius) away from the centre point. Y is 
then positioned Бу the COS and SIN functions in lines 190 апа 200. 

Spectrum: For use on the Spectrum change ** to À in line 30, and delete line 160. 
Change line 70 to read 70 PAUSE 0. In lines 190 апа 200 the centre point must be set 
as plot co-ordinates 84, 82, with LET X=84+(R*COS A*SC) and LET 
Y = 82 + (R*SIN A * SC). Line 210 must have the limits of X and Y set at 255 and 176 
respectively. Line 270 should read PAUSE 0. The program will then run, but you can 
also modify it to use the DEF FN and FN instructions: Define the function in line 50, 
with a DEF FN a() - SIN A * 3 or whatever the derived function is, and use LET 
R = FN a() in line 180. Change the instructions in line 40 to suit. 


ле REM “POLAR” 

Ба PRINT TAB 8; “4FOLAR ғістат; 
TAB а; жж аа ааа” 

Зе PRINT ,,"FLOT ROUTINE FOR б 
OLAR" , "COORGDINATES ENTER FUMCTI 
ON TO^,"BE PLOTTED WITHOUT USE О 
Б #4", "(RAISED ТО POWER! FLUMCIIO 
M.USE^,"SINsSINsSIN,NMOT SXMsa3,7 
OR" “EXAMPLE.USE A FOR ANGLE.“ ,” 
YOU MUST ALSO ENTER SCALE “ , "FRc 
TGR ANG ANGLE INCREMENT.” - 

42 PRINT ,, ENTER EMPRESATON 1 
о BE PLOTTED” 

S@ INPUT AS 

ба PRINT “ENTER ANGLE IMCREMENM 


7a INPUT РЯ 
aae PRINT “ENTER SCALE ҒОСҒОЭНЭС” 
а INPUT 5С 
imo СЫЗ 
269 КЕМ ЖРБІМТ RAES RHE PLOT 
INFORMAT ION +s 
i120 FOR F=1 ТО 282 
120 PRINT AT 11,Ғ,;”,%” 
250 PRINT AT F,28;":”" 
142 NEXT F 
icd PRINT AT @,32;R3;RT 32,393; “2 
.F.2'"; SC; TAB 18; "RMGLE INC. =” ; еЗ 
15а FAST 
369 REM #ROUND THE CIRCLe, SYES 


iFa FOR я-а TO 2xPI STEP OR 
i179 REM #EVALUATE FUNCT IQI H 
ізе LET R-URL RS 

139 REM sNEXT LINES GET J," 
CONVERTED TO POLAR СОБ RM SIM: 
COORDINATES, TIMES SCHLE ғостовк, 
AND SET WITH CENTRE AT 22 224 
290 LET X-204iRxCOS Bs5cCi 

200 LET Yz204 iR 351N nasci 

210 IF x»60 OR XQ OR Yia OR у 
сә THEN сото 252 

220 PLOT X,Y 


499 


=5@ NEXT R 

24e сото 292 

250 PRINT AT 19,2,’ "OUT оғ BLUT 
RANGE. REDUCE SCALE”, “ғастов,” 

=68 few NE ‘PRESS B KEY, THEM ЕВР 


289 GOTO өе 
290 REM #FINISH# 


+5. 
Set. =; a 
ANGLE INC., =, G= 


2. Home Accounts 


Program allows household expenses for each day for a month to be entered under 
various headings, which may of course be changed to suit your needs. Income is 
entered, and credits may also be input under any heading. After entries have been 
made, a statement of account is derived, which may be printed out. A breakdown of 
account by heading can also be printed, and the program and data saved to tape so that 
future entries may be added. 

The data is stored in string arrays, and these could be increased up to the limits of 
memory if a longer period were to be catered for. The program is menu-driven, and all 
inputs allow the user to check for errors and re-enter if necessary. 


> REM "HOME ACCOUNTS" 
10 REM *INITIALISATION* 
ZO LET TOTAL=0 
ЗО LET I=1 
40 LET C=0 
50 LET Z$="END " 
61 REM жАККАҮ DECLARATION* 
е2 DIM D$(3156) 
é3 DIM I$(31,1)2 
65 DIM АСЗ1› 
ее DIM A$C10) 
67 DIM (%(631) 
ев DIM К%(6315) 
&v GOSUB 170 
70 REM *MAIN МЕМ 
3 CLS 
75 PRINT АТ 0%8: "HOME ACCOUNTS 


77 PRINT АТ 1%8:"---- -------- 


80 PRINT АТ 4:10: «MAIN MENU*" 
£1 PRINT AT 5%11:"---- ---- 


500 


82 РКІМТ AT 7»2: "А"; АТ 7,103" 
TO ADD AN ENTRY" 
ӨЗ PRINT АТ 9:2: "5"; 
FOR ACCOUNT STATEMENT" 
84 PRINT АТ 112: "С"; 
;"FOR CODE BREAKDOWN" 
83 PRINT AT 13,2; "X"; 


;"TO EXIT" 


AT 9310:" 
AT 11310 


AT 13:10 


86 PRINT АТ 15%8: "ОРТІОМ 2" 
87 INFUT 0% 

88 IF 0Ф-"А" THEN GOTO 310 
8? IF ü$-"S" THEN GOTO 610 
90 IF G$-"C" THEN GOTO 805 


100 


IF 0%-"Х" THEN STOP 


120 PRINT АТ 1538: "UNKNOWN OPTI 


ON: "70$ 


130 PAUSE 100 
140 PRINT АТ 15:8;" 


150 GOTO 95 


160 КЕМ 


170 LET 
180 LET 
190 LET 
200 LET 
210 LET 
215 LET 
220 LET 
230 LET 
240 LET 


жж 
жж 


ЖЖЕХРЕМБЕ CODE 
*#INITIALISAT ION 
C$cioz"o" 
K$(1)="GROCERY" 
C$C2)z"P" 
{$(2)="PETROL" 
C$(s9="C" 
K$(3)="CAR REPAIRS“ 
C$Cc45z"R" 
K$(4)="RA TES" 
С$%$(5)="М" 


250 LET K$(S5)="MISCELLANEQUS" 
260 LET C$cé)="I" 

270 LET K$(6)="INCOME" 

280 RETURN 


300 REM #INFUTTING ПАТАж 
310 CLS 
320 PRINT AT 0:8; "НОМЕ ACCOUNTS 


330 PRINT АТ 1:38; "---- -------- 


350 PRINT АТ 5:57" T 
360 PRINT AT 4,2; "ENTER DATE (E 
б. 25 NOV: OR PA VEND. ae 
FINISH)" 

370 INFUT D$(1) 

380 IF 0%(1)="" THEN GOTO 370 
387 PRINT AT 4927" 


386 
390 
392 
)?"; 
394 
395 
396 
398 


IF П%(12-7% THEN GOTO 570 
РКІМТ AT 5,5; "DATE: ";D$(1) 
PRINT АТ 1035; “СОЕКЕСТ (Y/N 


INPUT Q$ 
IF @$="N" THEN GOTO 250 

IF 0% <> "Y" THEN GOTO 394 
PRINT AT 10.53" 


399 PRINT AT 11557" 


501 


439 


GOSUB 1000 
PRINT АТ 16,5; "EXPENSE CODE 


INPUT I$CI) 
IF I$(I)z"" THEN GOTO 430 
GOSUB 2000 


» FOR J=1 TO é 


IF 1%(12-С%(.1) THEN GOTO 44 


NEXT J 
PRINT AT 7:95; "UNKNOWN EXFEN 


SE CODE: ";I$CID 


440 
441 


442 


FAUSE 100 
GOTO 410 


РКІМТ АТ 739:"EXFENSE CODE: 


"PES CJ) 


444 
)?" 

446 

447 


448 
449 
460 


470 


PRINT AT 11:5; "CORRECT (Y/N 


INPUT 0% 
PRINT AT 11953" 


IF @$="N" THEN GOTO 410 
IF Q$ <> "Y" THEN GOTO 444 
РКІМТ AT 13,53" 


PRINT AT 9,9; "AMOUNT (- FOR 


EXPENSE) 7" 


480 
483 
487 


490 
500 
22"; 
510 
220 
530 
932 


534 
536, 
эзе 
540 
550 
560 
970 


INFUT A$ 
IF A$="" THEN GOTO 480 
PRINT AT 9357" 


FRINT AT 9:5; "AMOUNT: “FAG 
PRINT AT 13,5; "CORRECT (Y/N 


INPLIT Q$ 

IF Q$="N" THEN GOTO 460 

IF 0% 4» "Y" THEN GOTO 510 
PRINT AT 12,5; " 


PRINT AT 9557" 
PRINT AT 7,55" 
LET ñ(I)= VAL A$ 
(ЕТ IsI-*1 

LET C=C+1 

GOTO 350 


PRINT AT 10,3; "00 YOU WISH 


ТО SAVE THESE": AT 11,2; "ENTRIES 
(Y/N) 7" 


575 
380 


INPUT 0% 
IF Q$="N" THEN GOTO 73 


589 IF 06 <> "Y" THEN GOTO 575 


590 


PRINT АТ 10,2;"5ЕТ UP CASSE 


TTE RECORDER: WHEN READY PRESS A 
NY КЕҰ" 


595 
596 
999 


IF ІМКЕҮ% ="" THEN GOTO 595 
SAVE “HOME ACCOUNTS" 
GOTO 73 


600 REM *STATEMENT OF ACCOUNT 


902 


610 CLS 
620 PRINT TAB 5: "ЗТАТЕМЕМТ OF A 
CCOUNT" 

630 PRINT TAB 5%"-------- -- -- 


640 PRINT 

650 PRINT "DATE": TAB 8% "ТҮРЕ"? 
TAB 15: "СК"; TAB 25; "DB" 

660 PRINT "eese" TAB Bi "е7 
TAB i357 "-<-"3. TAB 257 "==" 

670 FOR I=1 TOC 

630 PRINT В%(10: TAB 2:1%С12; 
690 IF А(12>0 THEN GOTO 720 
700 PRINT TAB 25; ABS ACT) 

710 GOTO 730 


720 PRINT TAB 15;А(1) 

730 LET TOTAL=TOTAL+ACI) 

740 PRINT 

750 NEXT I 

793 PRINT TAB 2ОҒ”------ " 

755 FRINT "BALANCE"; TAB 20; TOT 


766 PRINT AT 2132: "COPY TO PRIN 
ТЕК СҮМ) 7" 

767 INPUT Q$ 

768 IF ü$-"N" THEN GOTO 73 

769 IF 0% <> "Y" THEN GOTO 767 
770 PRINT AT 21,23 "ЗЕТ UP PRINT 
ER AND FRESS A KEY" 

773 IF INKEY$ ="" THEN GOTO 773 
775 PRINT АТ 21927" 


780 COFY 

790 GOTO 73 

S00 REM **BREAKDOUWN OF жж 
XACCOUNT BY CODE жж 

905 CLS 


810 PRINT “STATEMENT OF ACCOUNT 


830 PRINT "CODE"; TAB 15% "TOTAL 


840 PRINT 

250 LET J=1 

255 (ЕТ TOTAL=0 

860 FOR Ісі TO C 

$70 IF I$(I)=C$(J) THEN LET TOT 
AL=TOTAL+A(T) 

280 NEXT I 

990 PRINT K$(J); TAE 15; TOTAL 
900 LET J=J+1 

910 IF J <= 6 THEN GOTO 855 

926 PRINT АТ 2192: "COPY TO PRIN 
TER (Y/N? ?" 

927 INPUT Q$ 

928 IF ü$-"N" THEN GOTO 73 

929 IF 0% <> "Y" THEN GOTO 927 
эзо PRINT AT 21,23 "БЕТ UF PRINT 
ER AND FRESS A KEY" 

940 IF INKEY$ ="" THEN GOTO 940 


503 


PIO FRINT AT Z1s27" 
veo COPY 
990 GOTO 73 


1000 REM 33433) )9 9 09 9 ! ) 9 09 X 9 * 99€ 
X*EXFENSE CODE МЕМІІжж 
*#*SUBROUT INE жж 
3C EIE ЗЕ ЗЕ ЕЕ ЗЕ ЗЕ ЭЕ ЭЕ ЭЕ ЗЕ ЕЕ EHR 

1020 PRINT АТ 7,5;"*ЕХРЕМ5Е CODE 

МЕМИ+ : 

1090 PRINT AT бұз!” eee m ne 


1050 PRINT AT 9*5;"G"; AT 2157" 
GROCERY " 

1060 PRINT AT 10,93 "Е"; АТ 10,15 
т КЕТКЕШ." 

1070 PRINT АТ 11:5;"C"3 AT 115915 
;"CAR REPAIRS" 

1080 PRINT AT 12,5; "Е"; AT 12,15 
; "RATES" 

1090 PRINT AT 12:5;:"M": AT 13515 
; MISCELLANEOUS" 

1100 PRINT AT 14,53 "1"; AT 14515 
; "INCOME" 

1110 RETLIRN 


2000 PRINT AT 16,5;" 
2010 PRINT AT 14957" "; АТ 14515 


2020 PRINT АТ 13,93" "; AT 13315 
2050 PRINT АТ 12957" "; AT 12,15 


= d 
y 


2040 PRINT AT 11,5;" "Ó"; AT 11,15 


ә 41 
y 


2050 PRINT AT 10957" "; AT 10,15 


= и 
, 


2060 PRINT AT 9,9:" "; AT 9?,15;" 
2070 PRINT АТ 3.93" 
2080 PRINT AT 7,93" 
2090 RETURN 
3. Resval 


Program derives the preferred resistor value (i.e. the closest standard resistance) from 
inputs of the voltage and current required in a circuit. From these inputs (in volts and 
amps) the actual resistance is calculatead by Ohms Law (R = V/I). This value, rounded 
to two significant figures, is then used to calculate the value L, 10 to the power L, being 
the multiplier for the resistor value. The values stored in the array X(13), entered as 
shown in the first program, are then compared with the calculated resistance. The first 
value stored in the array which gives a value greater than R is then used to print out the 
preferred value for the component. The current and power using a resistor of this value 
are then printed. The user may then choose to run the calculation again with different 
inputs until the best solution is achieved. This illustrates the basic principle of 
computer-aided design (CAD) of circuits, where the derived theoretical values are 
modified to suit the actual components available. 


504 


The array creation program and data values (of resistors with +10% tolerance) are 
given below. This program is then edited out, and RESVAL entered. Alternatives to 
storing the data in an array would be to assign each value of the array X with a LET 
statement, or, if using a Spectrum, to place the values in a DATA statement. Both 
these methods would eliminate the problem of avoiding the use of RUN. 


Spectrum: Change ** to ^ in lines 220, 240 апа 270. 
Change line 340 to read 340 SAVE ‘‘RESVAL”’ LINE 10 
Delete line 350 
As noted, the program could be modified to use the DATA and READ 
statements. Insert a line 340 with the data as given below, and insert 


215 READ X. Change X(N) to X in lines 220 апа 240. 


1@ REM ##RESISTOR VALUES INTO 
ARRAY * x 

20 REM жы ІМЕЗ EDITED GUT RFTE 
R ENTRY OF URLUES == 

ЗӨ REH жжТНЕМ RESURL PROGRAM Е 
NTERED xx 

да DIM X113? ue 

50 LPRINT “ARRAY VALUE 

60 LPRINT 


TO XA. VL oam 
ве LPRINT a te TE 
зе INPUT X tL. 


18090 LPRINT TAB т;хаз 
110 NEXT L 


ARRAY VALUE 


"ТЕГҮ 
отын о 
$ 
“ 


RRMA KKK KX 


май a? uà чн 
m 
0 


19 REM xRESURL x 
20 PRINT "RESURL" 


48 PRIN! "PROGRAM DERIVES PREF 
ERRED VALUE"; ТАБ Ө; “OF RESISTOR 
FROM INPUT"; TAB ә; “VOLTAGE AND C 
URRENT VALUES" 

50 PRINT _ > 

$09 PRINT “PREFERRED UALULECS STO 
RED IN ";THB е; “ARRAY . DD NOT REUN 

PROGRAH.USE"'; TRB в; “сото 100." 

79 PRINT “SAVE WITH GOTO 340.' 

ба PAUSE быб 


180 PRINT SYOLTAGE ws 
ise PRINT TAB 128;U;" VOLTS" 
140 PRINT “CURRENT т”; 


160 PRINT TAB 12,;,1;" AMPS” 

170 LET R-INT (.Мх106/1) 7100 
1500 PRINT 

"RD = зан “ACTURL RESISTANCE "; 
t's .. H +: 

әде LET L=INT (LM Rz2. 303} -1 
210 FOR N=1 FO is 

220 IF Ri=X (Ы) 108x*x«L THEN СОТО 


230 NEXT N 

243 LET x=X (N) z10 жж 

258 Ре "PREFERRED RESISTOR: 
53 >- Ж? . а. C .. 

260 PRINT “GIVES CURRENT "; INT 
(Uuxl28Q^7X)7100;" AHF 


505 


27m PRINT "BND “ІМТ iíUxsecÉelg. 
ы), „ез. cO атте 

232 PRINT 

сай PRINT “AGAIN? (У мә `` 

see INPUT Q 

310 IF @$="N" THEN STGP 

320 CLS 

330 сото заг 

340 SARVE “RESURS 

350 GOTO 1@ 


4. Matmult 


Program multiplies two square matrices. À two-dimensional matrix is stored as a two- 
dimensional array, with the size input. Matrix multiplication requires the number of 
columns in one matrix to be equal to the number of rows in the other. The matrices are 
set up as square arrays of equal size in this program, and nonsquare mtrices may be 
multiplied by entering 0 for the elements of a row or column which is unused. Users 
familiar with matrix arithmetic will be able to derive from this program the routines to 
handle other matrix operations. The method involves nested FOR-NEXT loops, in 
conjunction with three arrays in this program, the third array holding the resultant 
matrix. 

Other points to be noted are the input and error routines. The input routine prompts 
for inputs by row and column number, and when all elements have been entered the 
error check subroutine is called, so that the user can check the whole matrix at once. 
This avoids the possibility of confusion over row/column numbers. 


REM "MRTHULT'" 
REM #BETTER IN FRSTs 
> FAST 
10 PRINT "2D MATRIX вич T IP ICA 
TION", жен ннн ннен + жя +++ ж +++ ++" 
20 PRINT AT 3,0; “MULTIPLIES SQ 
HARE MATRICES." : AT „А; "TO USE F 
OR NONSQUARE MATRICES” , ENTER e 
TRIX SIZE ТО ACCOMOLATE”, "ANE ЕМ 
TER ZEROES.E.G ТО MULTIPLY", Мг 
= 3) ET". = Жы ” 23 әзі % 
38 PRINT’ "use NS ps Haters зге 
NTERING","1 COLUMN AND i ROW O 
REST @.",,,ENTER HATAICES 8 


ITN 


=a PRUSE 200 
се PRINT AT 21,2,” 43EMTER MRI 


aa REM 4D INENS TOM ISF 2 оны 

RESULT MATRICES+ 
зе DIM Я(5,53 
зап DIM B(5,5) 
1210 DIM С(5,5) 
128 CLS 
іза PRINT "ENTER MATRI” 3°, , ЕРІ 
TER @ FOR UNUSED ELEMENTI” 

249 FOR F=1 ТО 5 
ісе FOR N=1 TO 5 
158 sarc AT 21,0; “ROU ";F." со 


179 INPUT AIF, м) 

50 PRINT AT Ғаз, NxOG-O6,mpmpmifF,Ma 
150 NEXT М 

2220 NEXT F 

210 REM ҰМ IDENTIFIES MATRIA FG 
adi SUBROUTINE + 

=зё GOSUB See 


2590 PRINT "MATRIX 2” 
250 FOR Ғ=1 те 2 

270 FOR М1 

2580 PRINT Ar 317 5%; “ROW “;F; ”7 со 
омм ‚м; 

239 INPUT ӛсе, м: 

39090 PRINT AT Fe3, N#6-6;,8 TF, 


506 


34g u səə 
oo. ыы “MATRIX 1 + MATRIX 2 


=1 TO Š 
Poe TG 5 


` на TO S 
404 LET СР, М =C Р. МУ eR iF Li ғы: 
+1@ (ЕТ СР, М) SINT (Clr. N} +1E= + 


di SLES 

428 coon AT ҒұЗ,ыіұб-б; C tF Р 
dix 

339 mr 
450 NE 

_ +58 PRINT AT 21.8; "INPUT Cicory 
|; RIRUN) OR ECE мб)" 

i70 INPUT 2% 

IF Z$z"C" THEN COPY 

IF Z$="R" THEN RUN 


GOTO 786 
REM «ERROR SUBROLUTINE:x 


HE 
PRINT AT $0.0." QRE ALL ENTE 
: OR NJ)" 


Gl 
ШІ 
л 
Ci 
n 
4-2, 
"zr 


GUOJ Go 


Hl 


БФ 

F Бф-“Ү” THEN RETURN 

PRINT AT 21.9; "RON нен INT 
CT ENTRIES?" 

INPUT EN 

QR F=1 TO EN 

PRINT RT 20, n NS AT zi. 9; F $ 
21,0; "ERROR “;Ғ; ROW 

INPUT R 

puri zd 21.7; COLUMN т“ 


PRINT AT 21.0. R$: 22.8; “E 
SEBUT M NUMBER 


IF M=1 THEN LET R:!R,Ciz 
IF Mz2 THEN LET EiR,.Z;z 
PRINT AT ntes Cx#6-6; * E 
BRx2.C*5-6,N 

NEXT F 

PRINT AT 21,0:R$ 

сото S10 

REM #END 


Gams 


«LO Uf 33 4 co po eat Qc C 
т 


“. 


ew 
<.. 


DU n en em gu cn A C c on Tt cr fl inen enm pe p. eq 


mp C d D СД f D FE SiC CO <А 
AOS әәболоцоюш бу 


ENTER MATRIX 1 
ENTER @ FOR UNUSED ELEMENTS 


i = 5 
3 о e 
a ә ә 
MATRIX 2 

© ә 4 
ә a = 
a a e 


HARTRIX 1 ж MATRIX 2 GIVES: - 


e e a32 
e а е 
о e e 


INPUT CICOPY) ,RIRUN: OR E (END 


507 


5. Fruit 


Program simulates a fruit machine. The program allows you to continue playing until 
your money runs out (which it will eventually) and you can then ‘‘borrow’’ more. 
Points to be noted in the program are the overprinting of a string to simulate the 
spinning of the wheels (lines 200 to 230), and the logic used to check wins and amount 


(if any) won, in lines 250 and 260. The program loops back from line 290 to line 140 
unless the money has all gone. 


Spectrum: Change line 60 to read 60 PAUSE 0. 
10 REM "FRUIT" 


NT 1i rh 
зә PRINT "YOU HAVE SAP 
BLE.", “EACH ROLL COSTS 10 PENSE. 
ай PRINT +anPRVOUTS: = THE Sane 
PHYS 10Р"; S:°S THE SAME Ege 
s 40P"; TAB SS "ЕХбЕРТ REROMHICH E 
SO PRINT ,,"PRESS A HEY TO STA 


INKEY S$=""" THEN GOTO 6&8 


- 
- 





14 4 4 CTI 
mao 

th 

Том 

Т 

Qz 


(SS STN P 
DM тог гон 


# x INITIALISE «PRINT +Q + 


mi fui co 
3)! 20 P Pm mmm ПІГ ТТІ 
HHH x i 





EBER; T Б | ; 
RINT AT 19.8; 55 5 То £ 


+ 


HQ IF INKEYS<¢>°S" THEN GOTO 34 


RHEE EEE 
Gg 


ә 7) 
4 2.0010 


1 
2 REM ##5ЕТ WIN LINE + + 
= 


LET Bnga"t 

1-0 FOR Ғсі ТО 3 

162 LET A=INT RND +Ë x +: 
179 LET Б%-В%- Ж” +A 18: 


155 AME #*SPIN WHEELS% 


186 RE 

1989 LET fs) pw. 

200 FOR к=1 TO 1 

210 PRINT AT 9.12;F$i01 TG ©) 
220 LET F*$=F$íŠ TO »?«rF&il TO ZS; 
230 NEXT F 

234 REM 

235 REM *##PRINT WIN LINES + 

256 REM 

249 


3: 


PRINT AT 9.12: 5$ 
+ 
14393 +484425 = 


245 REM #xCHECK WIN: 
250 LET U-(BE$£(2)zE$ 
3 3 


BS 16 (6) Li (Bs (4) =E $ (63 
255 REH AMOUNT BONE £ 


eod LET C=(.18 AND 15-і) 541 +0 & 
4,45 3) 4+(1.8 AND W=S AND БЕШ =” 


те LET C$=C$ (1) STARAS (Vet Ciz 
\+Сс-.1а) 
REH 


Y 
ңғ. 


du 
GDG DAG JIC 
өпаьовбайь 


(i SHOE Se олы 


=] 
O 
D 


EL XxCHECH IF SOLVENT +E 


RINT RT 3. C$ 
N Е Cs (Š 9:5 ) >ш.10 THEN 


FIOI 


F. + +МОМЕҮ SPENT z £ 


Eri AT 3,.,0;"' xYOU ARE ERU. 
TAB ә; “BORRÓ ом £2 TIY OR м! 


a Mg 
LS 


MS="Y"' THEN GOTO әт 
INT "BETTER LUCK NEXT ТІМ 


G; 
s QIU fü FO fO nano TO 


:m 
POP ж 


rho CI Сау 
nur 


rm 


о 990 


un 
i 


508 


6. Lissajous 


A program to produce the intricate, interesting and delightful patterns, named after the 
mathematician who discovered the equation that produces them. You merely enter the 
values of A, B and C in response to the prompts and watch the patterns develop. 
Spectrum users can generate more complex patterns than ZX81 users, because of the 
higher resolution PLOT screen. 


Spectrum: Change line 80 to read 80 FOR F = 0 TO 200 STEP 2. This defines the 
number of points to be plotted. You can experiment with different values for STEP if 
you want more or fewer points plotted. Line 90 needs the two 30s changing to 120, and 
line 100 the two 20s changing to 80. A and B can both be input with values up to about 
10 on the Spectrum, so change the Input prompts to suit. 


REM #*#LIssAvouar 
REM PLOTS LISSATQUS PRTTERHN 


$ 
2 
З REM Я IS RELATIVE FREQUE HC? 
B IS REL. FREQ. Х,С 15 Y PHRI 


BIG MENT “INPUT A (INTEGER 1 T 

2@ INPUT A 

oe FRAN “INPUT E {INTEGER 1 T 
в 

SO PRINT "INPUT C (ANY HUMBER 

Ба INPUT С 


50 FOR ғ-о TO 20a 
90 LET Y=S3@+S04S5SIN (ConaPIaPsi 


те LET Xz20420*5IN (BxPIsT»igc 


110 PLOT v,x 
120 NEXT F 


"v заза, E ап = 1а ur" 
= = gd 2" я " N E ie а т 
> x to `. a в .. "ag "er 


7. Line 


This program gives the computer the capacity to draw a line between specified plot co- 
ordinates. The Spectrum possesses a LINE instruction that does this automatically, but 
Spectrum users may be interested in the method, which is the way the LINE instruction 
automatically calculates the points to plot. The program will run on the Spectrum if 
line 85 is deleted. As it stands, the program prompts for two sets of X, Y points, giving 
an error message if the points are out of range. Lines 110 and 120 calculate the X and Y 
axis differences between the specified points. Line 130 defines the variable A as the 
greater of these. DX and DY are the increments added to the values of X(1) and Y(1) 


509 


for plotting. In the loop (F = 1 to ABS A, since A may be negative) DX and DY are 
decremented or incremented (as X and Y are positive or negative) by the distance to be 
covered between points, divided by the number of steps needed. The program will 
accept further inputs as required, but does not provide input prompts (lines 210 to 


280). 


5 REM "LINE" " 

iO REM DRAWS LINE BETWEE POIR 
T.,(XC1),VYCLIIAND POINT ах+ш v 1E 
3 1 

20 DIM X12) 

25 DIM Y (2) 

50 FOR Ғ-1 TO 2 ©. -- 

40 PRINT “COORDINATES POINT “i 


со PRINT "A UGPLUSE Т" 
50 INPUT Р) 
70 PRINT 


^ 

( 

"Y VALUE Т” 
(F) 

> 


К 1355 THER 
PROGRAM AGRIN `` 





DY =@ 
16568 FOR F=1 ТО 65 n 
179 PLOT ОРТАҒЫ DY £w ££ 
180 LET DX=DX+X/ABS F 
190 LET DY= DT te CABS e 
2BO NEXT F 
219 REM FOR OTHER LINES 
220 REH M ркан жїл 
230 INPUT X(1) 


ТОЧНИОТ HS ИШИН 





8. Reverse 


The computer jumbles up a sequence of 9 numbers, and prints these (subroutine line 
500) after giving the instructions, by calling subroutine 1000. After each input by the 
player the subroutine at line 300 is called to print the altered sequence and check if the 
ordering is complete. If the sequence is correct, control is passed to line 2000 for the end 
routine, which gives the option of playing again. 

18 REM “REVERSE” 


20 PRINT TAB 10; "#REVERSEs" 
зе GOSUB 1000 

CLS 
45 DIN 


R (9) 
50 PRINT TAB 10;"'xREUERSEx' 
во PRINT AT 5,5; 


510 


ге GOSUB See 
өс LET GOES=Ə 
ae PRINT AT 15,0; “INPUT NUMBER 
TO REVERSE 77" 
100 INPUT R 
110 IF R:1 OR R»9 THEN GOTO 100 
120 GOSUB 380 
136 REM xxLOOP NEXT GO#* 
148 GOTO 100 
150 REM =#=# += # +++ + +++ + * + + +++ +++ Ж 


160 REH 
5020 REM rx*xREUERSE AND СНМЕСКЖжЖ 
310 REM +#SEQUENCE xx 
315 REM 


320 FOR F=1 TO INT (R72) 

USO LITT T=A tF) 

S4@ LET ЯР) =A (R-F+1) 

3550 LET AC(R-F+1) =T 

360 NEXT F 

370 LET CORRECT = 

3882 PRINT AT 5,5; 

390 FOR Fz1 "T 9 

400 PRINT atF2); T 

410 IF AIFI =F THEN’ LET CORRECT 
=CORRECT +1 

429 NEXT F 

4232 LET GOESzGOES—-«41 

440 IF CORRECT=9 THEN GOTO 2009 

450 RETURN 

460 REM #++ ++ +++ ++ +++ +++ ++ ++ +++ 


500 REM ##S5ET SEQUENCE #*¥ 
510 LET ACL) =INT (RND «933 +1 
TO 9 


S30 LET R (F) 2INT (RND#9) 41 
540 FOR N=F-1 TO 1 STEP -1 
550 IF ACF) =яМ) THEN СОТО S30 


550 FOR F=1 TO 9 

S90 PRINT R(tF),;" ”; 

600 NEXT F 

6180 RETURN 

620 REM =з» ++» ++» ++ +++ 
6380 REM 

19006 Бен *£*INSTRUCT IONS жж 


1820 PRINT COMPUTER GENERATES 
JUMBLED", "SEQUENCE OF DIGITS 1 


TO 9. 

1030 PRINT “YOU MUST INPUT A NUM 
BER 1 ТО 9, 

1040 PRINT “AND THIS NUMBER OF D 
IGITS,","STRHRTING FROM THE LEFTM 
OST a's "UILL REVERSE.YOU MUST GET 
2858 PRINT DIGITS IN ORDER LEFT 
TO RIGHT.' 

БЕРЕ PRINT ,, "PRESS R KEY TO STR 


1 @ PRINT s "THERE WILL BE A DE 
TU WHILE”, “SEQUENCE IS CREATED. 


10628 PAUSE 4ee00 
123290 RETURN 
4100 REM #= FF EXF FSH + + +++ +++ +1 ++ 


REM 
5000 REM sxEND ROUTINE 
2005 REM 
AT 20,0; "##SUCCESS IN 
2619 WES; GOES#s", "ANOTHER GO? CY 


м 
2030 IF Hao ye THEN сото 2050 


SYE 
9939 STOP 


9. Tools 


The program shows the principle of a programmer’s toolkit program containing useful 
program modules. You should add to this basic version any further subroutines or 
modules you want to have available. The inclusion of the BLOCKDEL program makes 


511 


editing out any modules not required for a specific program very easy. You may wish to 
add, for example, a round/justify subroutine for numbers, or a sorting subroutine 
Note the mnemonic for the error subroutine line number. When you add modules 
however, use variable names that you are unlikely to use in the program you are 
developing. Load the program before starting a program on the ZX81. 


Spectrum: For the Block delete module see BLOCKDEL. For Renumber module and 


Memory left see Section U of the text. Remember you can use MERGE to enter this 
program at any point (hence the high line numbers). 


m gj & Umm 


00 


S480 


S33S6+256*#PEEK 163387-PEEK 
SexPEERKR 16413; 


S540 
9550 


REM 
REM 
REM 


"TOOLS" 

£slLLUSTRHTES TOOLPRIT a 
езі ОНД) BEFORE START ++ 
Fe INPUTTING PROGHHRIX:X 
*xGO0SUB ERROR FOR =н 
+ *KHESSAGE 


##GOTOQ ашаа FOR aL Ock ++ 
#*#DELETE 


xxGOTO 9700 ғоя BENUM 
*xGüOTO S458 FOR MEMORY 
*LEFT 

ADO YOUR QUNM ROUTIN£ZI 
£ £ £ £ £ + £ $ £ + AHA $ $ HAAHA RABE 
ЕКРОВК =94.00 


ERROR MESSAGE 508+ 4 
* * Xx X X 3 3 Д < 3 HHH 


PRINT TAB 7, “#844 INPUT ERROR 


T); RERSRERHRHH4HHHHH ES” 
PAUSE 120 

REM #xHEMORY LEFT із 

are SHH HHeHAH HAHAH ++ +++ HSH SSS 


PRINT “MEMORY LEFT ="; PEE 


264325 —;3 


"1 
= 
— 
= 
ae 


APPROX,” 
STOP 


REM x*BLOCK DELETE:: 
REM 3 * s š 3*3 š € € s£ š š 


PRINT “FIRST LINE TO DELETE 
INPUT ST 
PRINT "LAST LINE ТО БЕ DE: = 


INPUT END 
LET RANM=16589 


9560 LET LNUM=2564PEERK RAMNSPEER 
(НАМ +1) 


3570 
+2 


3530 
ЕЕК 
9 


9560 


SLETE BLOCK 


ауа 


3500 IF 25б%РЕЕК БКИМФРЕЕК 
1 =9000 THEN GOTO 3832 


3512 
3520 
93530 


SUB , сота", 


354ea@ 


IF LNUMZST THEN LET LRBH=RA 


LET LLEN=PEEK S iRHlh-2!4286037 

(RAM +3) 

um “Бына END THEN GOTO ЭББ 
RAM=RAN4+¢4+LCEN 

GOTO 3568 

LET LLENsSRAM-*LLEN 2-154 

PORE LRAM+I1, INT YILLEN.2986561 

POKE LRRHM,LLEN-2SOGsPEER ILR 


PRINT “INPUT FIRST tei TO > 


= 


STOP 

REM #x#RENUMBER #+# 

REM ££ £ * * š * $ GR +++ 

LET mRhüM-zilesaa 

LET LINE =2@ 

LEIL ӘТЕРсіе 

POKE RAM, INT (LINE.2wU6 
POKE RAM*«1,i!LINE-z296643P££NH 


LET RAM=RAM+1 
IF PEEK RAMI >o4148 THEN GOTO 


=RAM+1 


= 


3770 


LET RAN 
URBI +S 
LET LINE-LINE-«STEP 

GOTO 9750 
PRINT | SRBEUBEREBA NOW DO Go 
“LINES 

STOP 


512 


10. Blockdel 


Program enables blocks of program lines to be deleted by a single line entry after the 
line numbers of the first and last lines of the block (ST and END) to be deleted have 
been entered (the program can also delete itself!). This is done by taking (line 9550) the 
start address of the program storage area (RAM) then finding (line 9560) the line 
number of the first line (LNUM). If this is the line number of the start line, the address 
of the first byte of the line length storage bytes (= RAM + 2) is stored as LRAM (line 
9570). The line length bytes are then PEEKed (line 9580) to find the line length in bytes 
(LLEN), before the line number is checked in line 9590 to see if it is the last line to be 
deleted. If it is, control is passed to line 9620. If it is not, RAM is incremented by the 
line length and four bytes for the program length and line number bytes, to get the 
address of the start of the next line stored in the memory, and the process is repeated. 
When the end line number has been located and control passes to 9620, the line length 
variable LLEN is made equal to the number of bytes between the first and last lines for 
deletion (this is why LLEN was found before checking if the current line was the last of 
the block) by setting RAM to be RAM + LLEN, i.e. the address of the end byte of the 
last line to be deleted. This value, less the address of the line length byte of the first line 
(stored as LRAM), plus 2 for the program line number bytes of the last line gives the 
number of bytes to be inserted by the POKEs of lines 9630 and 9640 as the new line 
length of the first line requiring deletion. The computer now thinks that the lines for 
deletion are all one huge line, and keying in this line number and pressing NEWLINE 

(ENTER) will delete the whole block. The program should be loaded for use on a ZX81 


from tape before you start working on a program. Spectrum users can use MERGE. 
Spectrum: Line 9550 (giving the start of the program area) must be changed to read: 


9550 LET RAM = PEEK 23635 + 256* PEEK 23636 


ле REM “BLOCK CEL 
3508 214 **8LOCK CELETES4 
3505 R * * +++ т 
3510 PRINT "FIRST LINE TO DELETE 


S528 INPUT ST | к 
S530 PRINT “LAST LINE ТО Sr Prise 


S54@ INPUT END 
assa LET ВАМ=16509 
S580 LET LNUM-2SBsPEEK Янә 


422” IF LNLIH=ST THEN LET ЬЯ = 


ssaa LET LLEN=PEER (8816523 PRSA 3=- 
ЕЕК (RAM+33 

S590 IF LNUM=END THEN GOTO Q822 
зеса LET RAN=RAN+44+LLEN 

2610 GOTO 9560 

3620 LET LLEN=RANF+LLEN22-L RM 
зеза POKE LRAMS1, INT ЕЧ soa 
29649 POKE LRAN,LLEN- 256 4PEEA tLe 


+1) 
$630 PRINT “INPUT FIRST MG TO Z 
ELETE BLOCK" 
S668 STOP 


10 REM "“BLOCKDEL" 
9500 REM ##ELOCK DELETE жж 
2505 REM EEE EH HE жы Ж 
2510 PRINT "FIRST LINE TO DELETE 
$520 INPUT ST 
9530 PRINT “LAST LINE ТО BE DELE 
TED?" 
2540 INPUT END 
9550 LET RAM=146509 


513 


2560 LET LNUM=275e% PEEK RAM+ FEE 
қ CRAM+1 > 

9570 IF UNUM=ST THEN LET LRAM=RA 
M+2 

7550 LET LLEN= PEEK (RAM+2)4+254.% 
PEEK CERAM) 

2590 IF LNUM=END THEN GOTO 2620 
7400 LET RAM=FRAM+44+LLEN 

9510 GOTO 60 


7630 LET LLEN=RAM+LLEN+2-L RAM 
7640 РОКЕ LFñM+1: INT (LLEN/226) 
9650 РОКЕ LRAM:+LLEN-256% PEEK xL 
RAM+ 1) 

9660 PRINT “INPUT FIRST»N/L Tü D 
ELETE BLOCK" 

76470 STOF 


11. Coder 


The computer chooses a four digit code sequence comprised of the digits 1 to 6. You 
input your guess for this code sequence. The computer prints your guess, checks for the 
number of digits in the correct place which correspond to the code, storing this as AST 
(for asterisk), and then checks through the remaining digits for numbers which occur in 
the code sequence, but are not in the correct place (DOLLAR). These values are then 
printed. This information helps you to refine your next guess. 15 goes are allowed, and 
if you haven’t got the code in 15 tries, it is printed out for you. The program is 
structured with a sequence of calls to subroutines. Note that the code can include 
repeated digits, and analyse the checking procedures to see how this is dealt with. 


REM “CODER " 
GOSUB 1006 
REM ТАНА а-а AND xx 


(Жы 


LET Neo" 22 345 
- 1i! = в“ 
FOR F=1 
LET Z n DENS сават «БҰМҒГАн6,ҙ €i: 


fos 





IF MARK=1 THEN GOTO 1:38 
LET GUESS=GUESS+21 
PRINT RT GUESS +2. 1i Gg: TRE 


GOSUB сос 

GOSUEB 608 

PRINT AST; TAB : DOLLAR 

REM ж%ҰЗЕЕ IF 15 TRIES жи 
+ xOR CODE CRRCHEDxrxE* 


F pe yku e e 
HUGO бб SEeaqQgqao был 


Sod J OAM mu vu e» Ct 


Тае 


219 IF AST=4 OR GUESS=1Z> THEN 
GOTO 2868 
220 REM ab icr adi TO NEXT GUESS 
езе GOTO 11 
240 REM ^o наказание най 
258 REH 
222 REN 
E *xCHECH INPUTrEE 
$95 BEN á 
: I F-L TO LEN &G 
аша Gg (F) аз THEN 24 om TODE 
< N 
аза ЫШТ LET MARAH = 1 
440 IF LEN 5Ф<>4 THEN LET ter. 


514 


450 IF NOT MARK THEN RETORN 
4603 Gn 2 NB AT GUESS-«3,.0; 

7 ";G$;"7? TRY AGRIN.* 
a7 PAUSE 
480 PRINT AT GUESS-T3,0;" 


42a RETURN 
435 REM хжхжжғғжхжкжғккккккк 


ЕМ 
5020 REM *=*=F IND NUMBER x + 


520 FOR F=1 TO 4 
530 IF AS(F)I<>GeiFs THEN ТГ 
570 


қой REM SSH x yx x z£ x x x x k x EEE 
520 REM xxFIND fj HRHUPIEEEE y x 


еге LET DOLLRARRzO 
өзе FOR F-1 TO 4 


FOR N=1 TO 4 
550 z g eth) rop On THEN GOÜTOG 


LET DOLLAR= DOLLAR +2 
LET AS(F) ="X 


44 4 CL Qn 
e guo 
OGOOGO 

r 
m 
-f 
G) 
2 
11 
ext 


RETURN 
22 REM хжххккккжккккккк 
730 REH 
1oo00 EE *3x INSTRUCT IONS + + 
EM 


іга PRINT TAB 12; VN SEEKER" | TRE 
12; “+СООЕК +; TAB 123;' ‘SEER ER К“ 
1@38 PRINT .. “COMPUTER CHOOSES = 
SEQUENCE ОҒ“,%4 NUNBERS.THIS I= 
MADE UP OF", "аму OF THE DIGITS 
i TO а”. “INCLUSIVE. DIGITS MEN EE 


R LE 
1 "YOU INET SEGUENCE 
5 TO TRY i Nb “MATCH THE CODE." 
1050 PRINT ,..^COMPUTER HILL PRIN 
T NUMBER OF B.SIGNIFYING CORRECT 
DIGIT IN". "RIGHT POSITION . CPU, ғ 
UMBER OF = ,HERNING € DIGIT Із G 
HESS WHICH 


19509 PRINT “OCCURS IN THE гомгазт 


ERS CODE, , BUT IS NOT IN THE БТ 
GHT PLACE.‘ 
41070 PRINT ,.," PRESS A KEY TS Ek, =; 
1280 IF ІМКЕУФ-““ THEN GOTG LGE 
1090 RETURN 
1192 REM EEEIEE 3 38 ККЕ 
5228 REM END ROUT 
: шо INE x x 
5929 НЕМ ast 4 THE? 
282 = ч GOTO 205 
2023090 PRINT "15 TRIES AND NO Sr: 
ESS.CODE"."uns "209 
5058 ERENT Mec 

сый: - " e E > è £z. 
na RTRS CESS ІМ í GUESS, 
cuo T “ANOTHER Ge Ti i 
т OR NOS GAME IMPLT 
2UTO INPUT MS 
zasa IF Мф-“У" THEN GOTG Zu 
2290 CLS 
заво ERUNT "DC BYE.” 
2350 RE 
292930 REM *xx«xxxrxENDEEXExEeEk 
3999 STOP 


"BB GUESS 





E 
1 
3 
3 


GG ts 


515 


S432 1:2 
2342 32 X 
5122 т. 
siloa е 1 
13923 | 9 3 
бізг i = 
1362 1 2 
4532 s uk 
S332 12 
4352 з 2 
3342 г е 
3512 4 0 
SUCCESS IN 15 TRIES? 


RNOTHER GAME? { INPUT Y OR H 


12. Plot 


A simple program to plot a graph of data points, with X and Y values input on the 
screen. Prompts for X and Y axis minimum and maximum values are made, and string 
inputs for the axis titles. These are then printed, and the data input is prompted. X and 
Y values for each data point are entered, which is then plotted, and more data is 
requested. 


Spectrum: Change line 310 to read PLOT 124244 * (X- AYy(B- A), 
12 + 156 * (Y — C)/(D - С) 


2 REM PLOT se 

дё PRINT TAB 6: BSR SE rei сут ET 
2à8 PRINT 

3@ PRINT "SET AXIS RANGES" 

40 PRINT “INPUT X AXIS MIN. vat 
SQ INPUT A 

SA PRINT A 

70 PRINT “INPUT X AXIS MECN Ue 
se INPUT Б 

за PRINT Б 

© PRINT “INPUT Y AXIS MIM. UAL 
а” INPUT с 

€ PRINT “INPUT Y AXIS MAX. VAL 
14@ INPUT D 


D 
i58 PRINT “INPUT X AXIS TITLE " 


IT a P 


іза PRINT X$ 

152 PRINT “INPUT Y AXIS TITLE ` 
“ора INPUT Y$ 

210 PRINT Y$ 

220 5 

230 PRINT AT 21,6;:X$& 

249 FOR I-1 TO LEN Y$ 

250 PRINT AT I«5,.0;Y&1I1j 

592 PRINT AT ә. 

228 ERENT S ©; INPUT N 

т NT AT @,0;" v 

266 таат 9 O; “INPUT ` 

UE. p I rius X-A Z CE; — € y , Seay 
зда GOTO 279 


13. and 14. Bidec 


Program converts binary numbers to their decimal equivalents. Two programs are 
given, differing in the conversion procedure applied to the binary number, which is 
input as a string. The algorithm of BIDEC*2 is more transparent than that of BIDEC. 
Spectrum users have the facility to input binary numbers directly (using BIN), but this 


516 


cannot handle numbers input in the course of a program, or generated by a program, 
in which case a routine of this type is required. 
BIDEC*2 


Spectrum: À not ** in line 50. 


š REM #BIDECs 
REM CONVERTS BINARY NUMBERS 


INTO ee tee 
18 "ENTER BINARY FORM" 
110 INBUT A$ 


158 PRINT Өй IN BINARY I2" 
348 LET R=LEN AS 

150 (ЕТ NSURL & was 

160 FOR Fz2 ТО 

17@ LET М S ема. F$ IF) 

ico NEXT 


RINT. 
әде PRINT N;" IN DECIMAL” 


o REN "BIDECx2" 
180 PRINT “INPUT BINARY NUMBER" 


SØ FOR F=LEN БФ TQ 1 STEP -1 
БӘ LET es иши BS i Fl £ xP 
Та LET P=P+ 

зе NEXT F 

oa PRINT B$; “=DECIMNAL “iN 


15. Hexdec 


Program converts hexadecimal numbers up to FFFF (65534 decimal) into decimal. As 
with DECHEX, the straightforward conversion of a character code to a decimal value 
which is possible on the ZX81 is more complex on the Spectrum. Line 130 in the ZX81 
version uses the value of the loop variable K directly to get the decimal value from the 
character code. On the Spectrum a counter loop is set up to hold and increment the 
value of K, and a new variable Z is used to hold the number by which K is to be 
reduced to give the correct decimal value from the hexadecimal character. 


Spectrum: Line 50 needs À , not ** 
Insert 55 PRINT ‘‘ LETTERS MUST BE CAPITALS." 
Insert 115 LET K = 48: LET Z = 48 
Change 120 to read 120 FOR Y =0 TO 15 
Change 130 to read 130 IF A(F) = К THEN LET N = ((K- Z)*X)+N 
Insert 135 LET K=K+1 
Insert 136 IF K = 58 THEN LET K = 65:1ЕТ Z = 55 
Change 140 to read 140 NEXT Y 


КЕМ x*HEXLDECrx 
4) 





INT 
50 PRINT "ENTER HEXADECIMAL NG 


"rr 
omm 
DA- 
хх I 
11 И 
wu 
+°: 
++ OO 
о 


LEN Ar 

ODE H$IF; 

„ЕН ris F} 

K THEN LET N=i t -2E 


“Wr TP I T 
жи 


X Gia p eu A 
` (S € 9 баб) (3 
Ж 
m 
4 

II Qo 


-. 
ээк Бараа л 


42 NEXT 


= 
(Ji 
б 
1 
D 
H 
z 
"n 
WX Th 


I9 ";N;" IM DECIMAL. 


517 


@ PRINT 

© PRINT "RHGRHIN'?7íN OR Y` 

© IF INKEYS$="Y" THEN GJOTG SS 
а STOP 


16. Dechex 


Program converts decimal (base 10) numbers up to 65534 to their four-figure 
hexadecimal/(base 16) equivalents. Hexadecimal numbers use the digits 0 to 9 plus the 
letters A to F. This requires a means of deciding which character is to be printed, after 
the decimal number has been broken down. On the ZX81 this is simple, since the 
(capital) letters A to F follow directly after the digits in the character code sequence. 
This is not the case on the Spectrum, and the gap in the sequence must be bypassed. 
CHRS can then be used to change the decimal values (0 to 15), into which lines 120 to 
170 break down the input number, to the appropriate character. 


Spectrum: Change 190 to read 190 LET X = 48 
Insert 205 IF X = 58 THEN LET X = 65 


TO 19 
IF FiiF)=y THEN LET AR&iF;-5H 
LET жн x+1 


Jj 


PRINT " IS “AS; IN HEX" 
PRINT AT ENR т NEWLINE 
UN AGAIN" 


Ces p. cana 


mor iU TO EO EG e [Ú [U R9 ei i RP ро RS F2 


1 REM DECHEX 
аа DIM Aig) 
сә DIM АФ (4) С 
за PRINT “DECIMAL BASE TO HENA 
DECIMAL BASENUMBER CONVERS TION™ 
4а PRINT 
БӘ PRINT "NUMBERS «85555 Gni“ 
ge PAUSE 35 
76 CLS 
S0 PRINT “INPUT DECINGL UD 0E" 
ай INPUT М 
аа PRINT 
12 PRINT N; 
ЕФ LET ACIVI=SINT (Ne 4 O58’ 
За LET B=N-A(1) £4636 
4@ LET ACBi=INT (8-258; 
ей LET C=E-F (2) +258 
ео LET Alsi SINT (O-26s 
79^ LET Aid) s=C-A(Ss £16 
зе FOR ғ-і TG 4 
acd LET X=26 
eo FOR Yzà 
із 
x 
e 
e 
e 
e 
o 
m 
a 
a 


%0-.| 


17. Gridhunt 


Тһе computer hides itself on ап 8 Бу 8 grid, which is displayed оп the screen. You input 
your guesses of the co-ordinates, the guessed square is marked, and if not correct the 
computer gives a prompt for its direction from this square, using compass directions. 


4 REM ¥*¥GRIDHUNT ж 
із PRINT —""iaekütal*sgs 
зә FOR Xz2 TO 18 STEP 2 
24. IF srana TREN COTO 46 
ху» 
40 PRINT AT 3,X; -";HÍi 14,х; "+ 


45 PRINT AT 441,22: "+"; RT xX+1l ,1 






G3 а. 
БО NEXT X 
60 LET E=INT (t(RND#53) +1 
78 LET М-ІМТ (RND zx: + 1 
Зб LET G=lE-1} +N 
ga LET H=@ 


518 


108 PRINT AT 3.28; "YOuR GUESS: — 
"AT 3,20; a ae ia 

Li@ INPUT 

128 PRINT Ят 5,26," ";яЯ; АТ 2,29 
з “DOWN?” 

130 INPUT D 

131 FOR Xz1 TO S 

152 PRINT RT 2-«Dzx2,1-24a0*2; Ж. 

133 PRINT AT 2+0%+2,1+я+2; "Y 

134. NEXT X 

135 PRINT AT 2t042,71+AR2S; “ж 

14@ PRINT AT 7,24;" ";г;ат 9,20 


145 LET М=М+1 

150 LET С= 9-1) #642 

160 IF C-G THEN сото зай 
2 


= 
190 IF N>D THEN PRINT "S"; 
2OD IF N:D THEN PRINT "N"; 
216 IF EYR THEN PRINT "E"; 
220 IF Е‹А THEN PRINT "UW"; 
әзе PRINT " “;TRS S2,"OF YOU" 
222 PAUSE 2080 
250 FOR X=3 TO із 


Р 
300 PRINT “GOT HME";ThB S2,;"IN ~ 


19 PRINT AT 20,89; “PRESS A KEY 
TO PLAY“ 
see IF INKEYS$="" THEN GOTO S2@ 
330 PRINT AT 20,8; 


349 CLS 
358 GOTO 1G 


18. Rescode 


Program calculates resistor values from inputs of the colour bands on the resistor. 
Three bands are input, end band first, using the abbreviations given. The first two 
bands define the basic value and the third the multiplier. 


32 BRYBESEOPE 
"ENTER COLOU У 
NDEAND FIRST" ee MESS 


3e INT 
айд PRINT “USE CODES AS БЕ ОШ: 
во PRINT ТАВ 6; “RED RE'; Тағ 


6; "BLACK 6L"; TAB 5:"BROUN BR" 
; TAB 6; “ORANGE OR’; TAS 65; "YELLOW 
"YE"; ‚таз 5; “GREEN GR’; TAB 6; “BL 
МЕ BL"; TAB 6; "UIOLET VI’; TAB & 
; GREY Gv" TAS o; "WHITE  UH",T 
nb Б; "GOLD GO"; TPE ё; “SILVER 5 


X^ 

вә FOR A=1 TO 3 

Ж. PRINT "COLOUR ";A; "7 n2 

ве INPUT C$ 

өй PRINT C$ 
100 IF C$-2"BK" THEN LET U=@ 
110 IF CS$-"BR" THEN LET Uzi 
12@ IF Сф= “НЕ” THEN LET Uz2 
130 IF C$-"0R" THEN LET Uz3 
140 IF C#="VYE" THEN LET V=d 
150 IF C#="GR" THEN LET Ч=5 
160 IF С%-"Еі. THEN LET V=s 
170 IF Сж-"МИІ" THEN LET М-? 
48@ IF cCH="GY" THEN LET УӘ 
190 IF C$-"UH' THEN LET Uz9 
оаа IF C#="GO" THEN LET U-i0 
210 IF Cs” SI" THEN LET іші 
эра IF n-i THEN LET F= 
2:30 IF R=2 THEN LET FoF He LG+u 
24G NEXT A 


250 METNT “RESISTANCE VALUE IS 
bea IF U9 THEN БОТО Зва 


519 


S10 PRINT " OHNS" 


S6Q PRINT Fev; 
370 PRINT " OGHHS 


19. Marker 


Program produces a marksheet for the pupils in a class after exam results are entered in 
five subjects, set in this program as English, Maths, French, Computing and Biology. 
The average mark for each pupil is calculated, and a grade breakdown of the results is 
printed, giving the total number of pupils in each grade. The grades are defined as: 


45% or less FAIL 
45 to 7596 PASS 
More than 75% DISTINCTION 


As initialised, the program allows up to ten pupils in each class. A pupil name is 
entered with the results in each of the subjects, and the average calculated. When all 
entries have been made, END is entered and the subjects, results and grades for each 
pupil are printed. The grade breakdown is then given of the number of pupils in each 
grade for each subject. 


1 REM “MARKER” 
5 LET Ti-e 
S LET Te=8 
7 LET Ta=e 
, 8 LET Z$-z"END 
да DIM AB$ir18,20) 
20 DIM RIID) 
25 DIM Di5! 
вв DIM PS: 
27 DIM F (Š 
За БІН S$1í5,1i0) 
да DIM H(3i@ S) 


52 PRINT “MARK SHEET" 
GE PRINT “аға, 


т^ PRINT "" 
зә PRINT “С 
100 LET Ісі 
іле LET Com 
РО КЕТ SEII: "ENGL FSH” 
АЗА LET ss te) =" МАТН" 
TES КЕТ 59:95 =“FRENCH" 
150 LET S$ it? -“СӘМРОТІМС" 
160 LEFT S$tS) ="BIOLOGY" 
22020 PRINT “EN ЕН NAME CENTER Ef 
p TO FINISH): ^" 
21ı1@ INPUT RSet 
ере PRINT REL 


ONHH 
а” ғ» 


езе IF mn$i1? 
езе SOSUE ive 
250 LET Ісізі 
ese LET C=C+1 


255 CLS 

268 сота гае 

Sag REM CALC RVERAGES 
элт соғу 


THEN бОТО See 


2) +R t L) 


ос 
өзе PRINT "МАМЕ :"; ABET? 


6249 PRINT "SUBJECT"; TAB iS; “HAN 
K"; TAR 2@; “GRAPE” 
сест eater ortega 
638 FOR U=1 TO 5 
6535 IF М(І,о3575 THEN GOSUB 2ee 


626 IF MET, 42 245 AND MOI, N 275 
THEN GOSUR 222080 
" ad YF Mi, <=45 THEN GOSUR 24 


520 


GEA PRINT ASE; TAS i15; MCI, iT 
AB 22; =s 

6S@ NEXT < 

665 PRINT "" 

666 PRINT “AVERAGE= “JANS 
667 PAUSE sae 

668 COPY 

өзе CLS 

67e NENT X 

700 PRINT “GRADE BREAKDOWN BY = 
UBJECT “ 

ТЇЙ PRINT “-------------------- 


?29 PRINT “SUBUECT'; TAB 25; "PD IS 
T.“ FRB PZ; PRSS“, TRE 27; “FRILL” 

725 PRINT ~” 

тз БОК (u=: FO 

740 PRINT 23 (49; TTAB ір TRB 

5e LET Ті-тізб cay 

Zëw LET Fe=TesP U.i) 

тта LET TAs Farr 522 


S20 PRINT “TOTAL”; TAS 15; 74; TAS 
22;T2; TAS 27,T3 


ase STOP 
BBR ROM INPUT гата 
ӘӘ FOR =i TO 3 
ДЕР. қ аын "USUBRBJECT “;5%%0»;” MR 
1858 INPUT Hr.) 
Өте PRINT Hül,.) 
Loan NEXT М 
11 RETURN 
зала REM DISTINCTION 
SQUIB LEF G$= DISTINCTION" 
2020A LET о =O tt + 1 
203a RETURN 
2200 REH PASS. 
гїї LEF G$ =“ PRES” 
2220 LET FP XG =P (<!) +1 
2230 RETURN 
mao REM FRIL 
242@ LET G£-"FRHIL" 
2420 LET Fifi =F (<i) жі 
2438 RETURN 


20. Indate 


Program is a date entry routine, with the input subroutine starting at line 10, and, 
nested within this, an error notice subroutine at line 250. On running the program, 
control passes to line 300, which has a short example of the manner of use of the 
subroutines. Subroutines are usually grouped at the end of a program, but they can 
equally well be put at the beginning, as shown here. With long programs, using the 
subroutines repeatedly, this can speed execution, since the computer counts from the 
start of a program to find the line number corresponding to a GOSUB or GOTO 
destination. 
1 REM "INDATE” 
2 REM xDHTE INPUT ROUTINES 
3 REN DATE ENTRY “CHECK SUBRO 
UTINES.ENTRY GOSUB iG.ERROR HESS 
ARGE GOSUB 250 
о GOTO See 
S REM +w == хз кк. 
Э REM ##DATE ENTRY SLE x x 
1e PRINT "ENTER DATE“ 
26 PRINT "OmnmV7" 
зә INPUT D 
49 IF D>=1 AND D<=5>1 THEN СОТО 


со GOSUB 250 
TO 20 
ге SEN ` ¿pra AL то 3203 
Әй IF M>=1 AND М<-іг THEN сото 
іре GQOSUB 250 


110 сото 74 
i209 PRINT “YEAR?T‘AS LAST 2 DIGI 


521 


130 INPUT Y 
140 IF vY»10 AND Y<9S THEN GOTO 


ісе GOSUB 2560 

169 GOTO 12€ 

170 REM CHECK DRY М5 MONTHS 
180 REM xLERHP ‘EARS | 

1a! IF ІМТ (t¥4i3@8) 24) <> (Y +1ƏG 
о) /4 AND M=2 AND с=з THEN GOTO 


сб REM SHORT MONTHS 
210 IF NOT ({M=2 AND D:28) OR t 
OR M=6 GR M-9 OR hH-11) AND 
Б-311: THEN GOTO 249 

220 GOSUB 250 

238 GOTO 19 

240 RETURN 

245 REM #=# =s X 3 + Xx x zy x x x Z= 3 3 % + X ЖЖ 
249 REM szszsERROR NOTICE SUBS 
250 PRINT “*###INPUT ERRORSss"," 
PLERSE FOLLOW INSTRUCTIONS", "ВЕ – 
INPUT REQUESTED DATA.” 

260 PAUSE 180 

270 CLS 

250 RETURN 

зой REM *¥##PROGRAM HERE ТО USE 

INPUT ROUTINESs*x 

318 REM #EXAMPLEs E 

320 PRINT “YOUR BIRTHDAY" 

3360 GOSUE 10 


2 
lI 
b. 


PRINT “BIRTHDATE: "`; BD; "+"; Б 


21. Headliner 


Program prints banner headlines on the printer, using the character arrays stored in 
ROM. As listed, the program allows the inverse characters of the ZX81 to be used, 
accessing the normal character (line 13@) to get the pattern of bits, but reversing this 
(1.е. swapping black for white) for printing (line 560). This procedure is not possible on 
the Spectrum, since the inverse forms are not included in the character set. The basis of 
the program is the reading of the character arrays (as with the BIGPRINT program in 
Unit U3 of the main text), but with the additional complication of reading the first bit 
of each byte, then the second bit of each byte, and so on, in order to print a character 
with a sequence of printer lines. 


Spectrum: Delete lines 40, 120. 130, 550, 560 
Change line 160 to read: 160 LET L = PEEK (15360 + 
C+8 * CODE L$) 


L REM *#HEADLINER: 
10 PRINT TRE 5; "im 
ез PRINT ,,; PROGRAM TO PRODUC 
E LARGE PRINT", "AS HERCLINES ALG 
NG PRINTER PAPER” 

GO PRINT ,,;" "INPUT ANY LEN&TH 
STRING." 

40 PRINT ,,;" YO: MAY USE ALL L 
ETTERS , NUMBERS", “AND GRAPHICS.” 
Se REM CIM RRRRY ТО STORE LETT 


во DIM Яќ54.) 

70 INPUT U$ 

ва FAST 

Эе FOR Е-і TO LEN U$ 

100 REM TRKE LETTER 

118 LET Іі %-ііФІҒ) 

124 REH IF CHR INVERSE THEN 
SURF FOR NORMAL FORM 

азе IF CODE L$»63 THEN LET L§$=C 
HR* (CODE ЦР) -126) 

140 REN SET кәм COGOZ3 

156 FOR с-а YO 7 
¿150 LET L-PEEK (7680«C45sCODE L 

j 





e 


522 


170 REM GET BINARY INTO BERRY 
180 FOR B-1 TO Gg 
190 IF L-exsINT (iL^2)-1 THEN GOT 


200 LET AIiSsC+B)} =o 
210 GOTO 238 

22 LET RíOGxc-5)-1 
230 LET L-IN!T (1/23 
240 NEXT B 

254 NEXT С 

рес GOSUB саз 

278 NEXT F 


сазда REM PRINT SUSROUT INE 
510 REM REVERSE LOOPS 

52 FOR X=8 TO 1 STEP -1 
S3@ LET niz fe 


540 FOR @ STEP -1 
550 REM REVERSE IF CHR INVERTED 
ВЕРОНЕ 


See IF CODE U$ (F?) 5655 THEN LET A 
{т €*5O-X) =NOT ACY x€ +X: 
2; REM PUT ONE ROR GF CHR INTO 


Ag 
оза LF R (Y*S+xXx)=1 THEN LET A$=A 
S90 IF RO xG4X)-0 THEN LET AS=R 


AS 
S20 LPRINT RS 
Do0 NEXT X 
64@ RETURN 


22. Input 


Program checks a number input as a string. This is a useful way to input numbers, as 
an error will not cause a program halt, as will happen, for instance, if a numeric input 
contains more than one decimal point. The program is listed as an input check for 
decimal currency, but is easily modified to suit any numeric input of a known form. 

The string input is checked by the subroutine at line 200, each character in turn 
being checked by means of its code to ensure it is either a digit or a decimal point. To 
check for multiple d.p.’s the counter S is incremented each time one is encountered. M 
is set equal to the number of digits before the d.p. A check is then made for S being 
greater than 1 (non-numeric character or more than one decimal place), @ (no d.p.), 
and for more than two digits after the d.p. Any error sends control to the error 
subroutine at line 400. This requests a re-input the number. The error check 
subroutine is then called recursively to check this input. A correct input will pass 
control back to the main program, where the user is given the opportunity to check that 
the input value is correct. 


1 REM "INPUT'" 
STRING INPUT CHELNED RS 


REM *#MARKERS x 
16 LET 5-0 
E ken ss 
М EMPTY LINE: 
20 LET E&-" £ 


** 


30 PRINT “ENTER BHOUNT . ENTER 
OUNDS.","FULLSTOP,P E E 
аа INPUT NG SPR Tec 

ET 

OFFER VALUE CRECH E 
entry Бай SMS SQ тысы Ut ID. 
Vt < ^ x` :yT x Г. ГЕ 

ТЕМ,Е TO RE-EN ж Т тнт 

78 INPUT аф 

SQ IF Ag="C" THEN GOTO 178 

30 IF A$="E" THEN GOTO асс 
,480 PRINT AT 20,9; “FOLLOM INSTR 
116 GoTo за 

120 PRINT AT 29.9;EF&: ES 
130 PRINT AT 20.0. “ENTER ЗІ ЕЕЕ 
T UBLUE." 

140 INPUT N$ 

150 PRINT AT зә.о;ғе:ғе 


923 


160 GOSUB 200 
170 Crs 

150 PRINT “END OF PROGRAM 

130 GOTO 999 

133 REM *ERROR CHECK + 

200 LET L=LEN N 

210 FOR F=1 TG L 

219 REM *CHECK NON-NOÜMEDRIL CRET 


220 IF CODE a. oa” OGR СТИХЕ ME 
F)»37 THEN LET S22 

2293 REM xCHECH ҒІҢА ЕТЕ 

ә: IF МФХЕЗ =". THEN LET 5-е еі 
240 am £L. p^ z"," THEN LET rtzF 


B= ЗЕ Ж OR 5,2 Gh £=& THE 
ы GOSUE 486 


333 REM sERROR FOUND: 
ғас PEINT AT 23, Oi“ £IMFLIIT INURL 
IDsRE-EMTER URLUÉ" 
418 INPUT H$ 
LET © 


412 E = = 
412 LET Мб 
420 GOSUB 200 
430 RETURN 
299 REM END 


23. Asteroids 


The program puts you at the helm of a Mars shuttle disguised as an asterisk. Avoiding 
the Nova Heat you have to weave through the strangely square low albedo asteroids 
that look surprisingly like inverse squares. Your controls are fairly minimal - not much 
money on the Mars run smuggling algae these days, so you have a button marked 1 to 
go left and one marked 0 to go right. 


The program cannot be simply modified for the Spectrum so this listing applies to the 
ZX81 only. 


= REM "ASTERDIDS" 


10 PRINT "x«ASTERDIDZ3«" 
20 PRINT 
Р 30 FRINT “AVOID BLACK ASTEROID 
40 PRINT “YOU STEER YOUR SHIF 
сж)" 
SO FRINT "BY PRESSING 1 TO GO 
LEFT" 
во РЕІМТ “AND 0 TO GO RIGHT" 
70 PAUSE 400 
во CLS 
90 РПКЕ 1641538 
100 LET 50 
110 LET C=10 


120 SCROLL 

130 PRINT AT 9230; 

140 IF PEEK ( PEEK oe M ыы F' 
ЕЕК 16399)<125 THEN GOTO 220 

150 PRINT "же 


160, LET L=C 

170 IF INKEY$ ="" THEN GOTO 190 
180 LET Г-С- (C>1 AND INKEY$ ="1 
"y+(C 212 AND ІМКЕҮФ ="0") 


190 PRINT АТ 8» ЕМО *20; "m" 
200 LET 3-241 

210 PRINT AT Soli" " 

220 GOTO 120 


524 


250 
260 
270 
220 
290 
300 
210 


РЕІМТ 5 

PAUSE 250 

CLS 

PRINT “PRESS NEWLINE FOR" 
PRINT "ANOTHER GAME" 
INFLIT A$ 

IF AS="" THEN GOTO ВО 


525 


Peter Morse is Professor and Head of Computer Science at the 
Polytechnic of Central London. He has wide ranging teaching, 
research and consultant activities in the fields of digital 
systems, software engineering and computer education. 


Ian Adamson is an educational consultant active in the design 
of technical and scientific courses, and the associated buildings, 
laboratories and equipment, working mainly on overseas 
projects. 


Ben Anrep is a Senior Programmer working оп 
microprocessor system development and software with the 
Computer Centre of the PCL. 


Brian Hancock is Senior Lecturer in Computer Science. His 
teaching and research activities include programming methods 
and the operation of computer courses for schoolteachers. 


The Essential Guide to Timex/Sinclair Home Computers is the only 
comprehensive guide to the world's best-selling and most inexpensive 


home computer, the Timex/Sinclair 1000 (also known as the Sinclair 
ZX81) and the new Timex/Sinciair 2000. The authors, highly respected 
computer science prolessors and consultants, take you beyond any 
instruction manual and present everything you need to know, in easy- 
to-understand language, about hardware, software and programming 
skills. The Essential Guide to Timex/Sinclair Home Computers covers 
all aspects of operating and programming Timex/Sinclair home com- 
puters, including: turning the machine on (not as obvious as you 
think!); the basics and the five points of Sinclair BASIC; designing 
programs incorporating subroutines, loops and nested loops; using 
strings, lists and arrays; generating graphics on the T/S 1000 and color 
graphics on the T/S 2000; addressing the computers memory with 
PEEK and POKE commands; and special tips on editing and debugging 
techniques. It also includes a complete program library, as well as 
many exercise and game programs to use while you learn, a section 
on applications, a simple guide to error codes, a special summary of 
Sinclair BASIC commands, an expianation of character sets and codes, 
and much more. This is the oniy book you will ever need for your 
Timex/Sinclair 1000 or 2000, and the perfect tool for building program- 
ming confidence no matter what kind of computer you own. 


oe Д |01/005і0Пе Book Cover by Zimmerman 
Я Published by Simon & Schuster, Inc. Foyster Design 
New York 


“Timex” is a trademark of Timex Computer Corporation. “Sinclair” is a trademark of Sinclair 
Research Ltd. Neither the author nor the publisher is affiliated with Timex Computer Corpora- 
tion or Sinclair Research Ltd., and neither Timex Computer Corporation nor Sinclair Research 
Ltd. has authorized the publication of this book. 


0553-0550 $8.95 0-671-47069-8